首页 > 代码库 > POJ 1276 完全背包

POJ 1276 完全背包

---恢复内容开始---

这道题就是明显的完全背包题啦,只不过物品的重量和价值是一样的。

我就是按照《背包九讲》中完全背包的思路,先把物品的数量 ni 按照1,2,4,8...的规律分解,然后直接用简单背包暴力

数据比较小,10种物品,每一种最多1000个,cash<=100000,这样子复杂度就是 10*log(1000)*100000,10的7次方刚好能过

下面是我的代码

 1 #include<stdio.h>
 2 #include<iostream>
 3 using namespace std;
 4 
 5 #include<math.h>
 6 #include<algorithm>
 7 #include<string.h>
 8 #include<stdlib.h>
 9 #include<vector>
10 #include<set>
11 #include<map>
12 #include<stack>
13 #include<string>
14 #include<queue>
15 
16 #define repA(p,q,i)  for( int (i)=(p); (i)!=(q); ++(i) )
17 #define repAE(p,q,i)  for( int (i)=(p); (i)<=(q); ++(i) )
18 #define repD(p,q,i)  for( int (i)=(p); (i)!=(q); --(i) )
19 #define repDE(p,q,i)  for( int (i)=(p); (i)>=(q); --(i) )
20 
21 
22 int dismiss[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
23 int ni[20], di[20];
24 int ci[110];
25 int dp[100010];
26 
27 int main()
28 {
29     int cash, n;
30     while( scanf("%d%d", &cash, &n) != EOF )
31     {
32            repA(0, n, i)
33              scanf("%d%d", &ni[i], &di[i]);
34            
35            int rd=0;
36            repA(0, n, i)
37            {
38                   int tmp = ni[i] + 1;
39                   int dt;
40                   for(dt = 1; dt < 11; ++dt)
41                   {
42                           if(tmp >= dismiss[dt])
43                             ci[rd++] = dismiss[dt-1] * di[i];
44                           else break;      
45                   }
46                   --dt;
47                   ci[rd++] = (ni[i] + 1 - dismiss[dt]) * di[i] ;
48            }
49            
50            memset(dp, 0, sizeof(dp) );
51            
52            repA(0, rd, i)
53              repDE(cash, ci[i], j)
54              dp[j] = max(dp[j], dp[j-ci[i] ] + ci[i] );
55            
56            printf("%d\n", dp[cash]);
57                                               
58                  
59     }
60     return 0;
61 }
View Code

网上还有个大牛的代码比完全背包有了一个数量级的优化,貌似有点复杂,不过还是推荐去膜拜啊~~~

链接:http://blog.csdn.net/lyy289065406/article/details/6648102