HDU 2844 混合背包、

题意:一个人想买手表,给你n个价值的硬币,然后给你n个价值硬币对应的个数、但是呢,这个人只知道这个手表的价格不超过m元、问他最多能买多少种价值的手表

思路:dp背包专题 但是- - 一直不知道该怎么dp 终于想通了、

PS:对于背包dp说一说自己的理解吧(虽然不知道有什么用)  一旦涉及到dp 你就要考虑dp数组里面存的是什么,另外一维数组的话你就要考虑dp[i]中,那个i代表的是什么,同理二维数组也是一样、  然后写出状态转移方程,你的状态转移方程一定要和你dp数组里面存的状态是相一致的、

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 const int qq=150;
 7 int a[qq],c[qq];
 8 int dp[100005];        //dp[i]代表价值为i能用硬币的最大数量、 
 9 int m;
10 void wanquan(int x,int y)
11 {    
12     for(int i=x*y;i<=m;++i)
13         if(dp[i-x])
14             dp[i]=max(dp[i],dp[i-x]+y);
15         else if(i-x==0)
16             dp[i]=max(dp[i],dp[i-x]+y);
17     return;
18 }
19 void beibao(int x,int y)
20 {    
21     int c=x*y;
22     for(int i=m;i>=c;--i)
23         if(dp[i-c])
24             dp[i]=max(dp[i],dp[i-c]+y);
25         else if(i-c==0)
26             dp[i]=max(dp[i],dp[i-x]+y);
27 }
28 void f(int x,int y)
29 {
30     if(x*y>=m){
31         wanquan(x,1);
32         return;
33     }
34     int t=1;
35     while(y>=t){
36         beibao(x,t);
37         y=y-t;
38         t=t<<1;
39     }
40     if(y)    beibao(x,y);
41 }
42 int main() 
43 {
44     int n;
45     while(~scanf("%d%d",&n,&m)&&(n||m)){
46         memset(dp,0,sizeof(dp));
47         for(int i=0;i<n;++i)
48             scanf("%d",&a[i]);
49         for(int i=0;i<n;++i)
50             scanf("%d",&c[i]);
51         int count=0;
52         for(int i=0;i<n;++i)
53             f(a[i],c[i]);
54         int sum=0;
55     //    for(int i=1;i<=m;++i)
56     //        printf("%d ",dp[i]);
57         for(int i=1;i<=m;++i)        //dp[i]不为0也就是说能用所拥有的硬币组成价值i 
58             if(dp[i])    ++sum;
59         printf("%d\n",sum);
60     }
61     return 0;
62 }

 去杭州前把这道题A了 没来得及记录下、 今天补上

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