8月4ACM集訓之---------背包問題

來源:互聯網
上載者:User

標籤:style   blog   color   os   io   strong   for   問題   

好想吐槽一下,每一個專題兩天,還要努力數排名,對我這樣一個比較笨又不是很勤奮的人來說,真心有點吃力,好多東西都只能做到一知半解————要加油了---不然會被鄙視的的

背包——通俗理解就是將背封裝滿的問題,其要求一般是使其價值最大

01背包:

 有N件物品和一個重量為M的背包。(每種物品均只有一件)第i件物品的重量是w[i],價值是v[i]。求解將哪些物品裝入背包可使價值總和最大。

每個物體都有兩個屬性,value和weight,而背包則有size,用V[i, j]用來表示從前 i 項{u1......ui}(背包中的物品)中取出來的裝入體積為size的背包的最大價值。

V[i, j] = 0       若i = 0 或 j = 0;

V[i, j] = V[i - 1, j]    若j < ui.weight;(當物品的重量大於背包承重時,就不巴物品放在裡面)

V[i, j] = max{V[i - 1, j], V[i - 1, j - ui.weight] + ui.value}      若i > 0並且j >= ui.weight

簡化後的模板未:f[v]=max{f[v],f[v-c]+w}(前i件武平放入容積為v的背包中可獲得的最大價值)

完全背包:

每種物品可以放無限放

多重背包問題:

每種物品有一個固定的次數上限

二維費用的背包問題:

二維費用的背包問題是指對於每件物品,具有兩種不同的費用,選擇這件物品必須同時付出這兩種代價,對於每種代價都有一個可付出的最大值(背包容量),求選擇物品可以得到最大的價值。設第i件物品所需的兩種代價分別為v[i]和u[i],兩種代價可付出的最大值(兩種背包容量)分別為V和U,物品的價值為w[i]。

例:杭電acm 2602

 

#include<stdio.h>#include<string.h>#include<iostream>using namespace std;int max(int a,int b){    return a>b?a:b;}int main(){    int t,n,m,dp[10001],i,j;    int a[10000],b[10000];    scanf("%d",&t);    while(t--)    {                scanf("%d%d",&n,&m);        memset(dp,0,sizeof(dp));        for(i=1;i<=n;i++)        {            scanf("%d",&a[i]);        }        for(i=1;i<=n;i++)        {        scanf("%d",&b[i]);        }        for(i=1;i<=n;i++)        {            for(j=m;j>=b[i];j--)            {                dp[j]=max(dp[j],dp[j-b[i]]+a[i]);                            }        }        cout<<dp[m]<<endl;            }    return 0;}

杭電     對布的裁剪問題

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;struct node{    int val,wei;} a[155];int dp[155][155];int main(){    int n,m,k,s,x,y,z,i;    while(~scanf("%d%d%d%d",&n,&m,&k,&s))    {        for(i = 1; i<=k; i++)            scanf("%d%d",&a[i].val,&a[i].wei);        memset(dp,0,sizeof(dp));        for(x = 1; x<=m; x++)        {            for(y = 1; y<=k; y++)            {                for(z = 1; z<=s; z++)                {                    int cnt = 1;                    while(cnt*a[y].wei<=x && cnt<=z)                    {                        dp[x][z] = max(dp[x][z],dp[x-cnt*a[y].wei][z-cnt]+cnt*a[y].val);                        cnt++;                    }                }            }            if(dp[x][s]>=n)            break;        }        if(x>m)        printf("-1\n");        else        printf("%d\n",m-x);    }    return 0;}

  

#include <stdio.h>#include <algorithm>#include <string.h>using namespace std;struct node{    int x,y,v;}a[20];int dp[1005][1005];int main(){    int i,j,k,n,X,Y,t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d",&n,&X,&Y);        for(i = 0;i<n;i++)        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v);        memset(dp,0,sizeof(dp));        for(i = 0;i<=X;i++)//二維背包        {            for(j = 0;j<=Y;j++)            {                for(k = 0;k<n;k++)                {                    if(i>=a[k].x && j>=a[k].y)                    dp[i][j] = max(dp[i][j],max((dp[i-a[k].x][j]+dp[a[k].x][j-a[k].y]),(dp[i][j-a[k].y]+dp[i-a[k].x][a[k].y]))+a[k].v);                    if(i>=a[k].y && j>=a[k].x)                    dp[i][j] = max(dp[i][j],max((dp[i-a[k].y][j]+dp[a[k].y][j-a[k].x]),(dp[i][j-a[k].x]+dp[i-a[k].y][a[k].x]))+a[k].v);                }            }        }        printf("%d\n",dp[X][Y]);    }    return 0;}

//求最小价值
#include<stdio.h>#include<string.h>#include"cstdio"#include<iostream>using namespace std;#define max 10000000;struct node{ int value; int weight;}a[10005];int dp[10000];int main(){ int t,n,m,m1,m2,i,j; scanf("%d",&t); while(t--) { scanf("%d%d",&m1,&m2); scanf("%d",&n);        m=m2-m1; for(i=0;i<=m;i++)         dp[i]=10000000;        dp[0]=0;        for(i=0;i<n;i++)        {            scanf("%d%d",&a[i].value,&a[i].weight);        } for(i=0;i<n;i++) { for(j=a[i].weight;j<=m;j++) {                 if(dp[j]>dp[j-a[i].weight]+a[i].value)                    dp[j]=dp[j-a[i].weight]+a[i].value;                 } }        if(dp[m]==10000000)            printf("This is impossible.\n");        else         printf("The minimum amount of money in the piggy-bank is %d.\n",dp[m]);         } return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.