HDU 1114 完全背包 HDU 2191 多重背包

HDU 1114 Piggy-Bank 完全背包问题、

想想我们01背包是逆序遍历是为了保证什么?

保证每件物品只有两种状态,取或者不取.那么正序遍历呢? 这不就正好满足完全背包的条件了吗

means:给出小猪钱罐的重量和装满钱后的重量,然后是几组数据,每组数据包括每种钱币的价值与重量要求出装满钱罐时的最小价值

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 using namespace std;
 6 const int qq=50000+10;
 7 const int MAX=1e8;
 8 int dp[qq];
 9 int v[qq],p[qq];
10 int main()
11 {
12     int t;scanf("%d",&t);
13     while(t--){
14         int a,b;scanf("%d%d",&a,&b);
15         int c=b-a;
16         int n;scanf("%d",&n);
17         for(int i=0;i<n;++i)
18             scanf("%d%d",&p[i],&v[i]);
19         for(int i=1;i<=c;++i)
20             dp[i]=MAX;
21         dp[0]=0;
22         for(int i=0;i<n;++i)    
23             for(int j=v[i];j<=c;++j)
24                 dp[j]=min(dp[j],dp[j-v[i]]+p[i]);
25         if(dp[c]==MAX)    printf("This is impossible.\n");
26         else            printf("The minimum amount of money in the piggy-bank is %d.\n",dp[c]);
27     }
28     return 0;
29 } 

HDU 2191 多重背包问题、

其实还是应用01背包的思想、不过这里有一个小技巧就是二进制表示法、

比如 13、可以表示成 1+2+4+5  这4个数可以组成1到13之间的任意一个数、

那么就可以多重背包拆分成01背包问题、

千万注意将空间压缩成一维的话是逆序遍历、这里解释一下 dp数组中的每一个值都是一种状态,该种状态在当前是独立的不受其他影响的,如果正序遍历的话前面得到的一些状态影响其他状态的生成、

- -、我是这么理解的、  总之你要dp的话就是... 唉本弱弱语文水平好差、

联想一下二维数组下是怎么更新状态的、再看看一维、这样就很容易理解了

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 const int qq=1000;
 7 int p[qq],v[qq];
 8 int dp[qq];
 9 int main()
10 {
11     int t;scanf("%d",&t);
12     while(t--){
13         int price,kind;
14         scanf("%d%d",&price,&kind);
15         int count=0;
16         int a,b,c;
17         for(int i=0;i<kind;++i){
18             scanf("%d%d%d",&a,&b,&c);
19             int t=1;
20             while(c>=t){
21                 p[count]=a*t;
22                 v[count++]=b*t;
23                 c=c-t;
24                 t=t<<1;
25             }
26             if(c){
27                 p[count]=a*c;
28                 v[count++]=b*c;
29             }
30         }
31         for(int j,i=0;i<count;++i)
32             for(j=price;j>=p[i];--j)
33                 dp[j]=max(dp[j],dp[j-p[i]]+v[i]);
34         printf("%d\n",dp[price]);
35         memset(dp,0,sizeof(dp));        //一定记得初始化、毕竟有很多组数据、
36     }
37     return 0;
38 }

 

posted @ 2016-04-07 21:07  我不萌、我要高冷  阅读(257)  评论(0编辑  收藏  举报