码迷,mamicode.com
首页 > 其他好文 > 详细

背包九讲之三(多重完全背包)

时间:2015-02-07 18:44:55      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

题目地址:http://poj.org/problem?id=1276

 1 /*
 2 有n件物品和一个容量为v的背包,第i种物品最多有n[i]件可用,
 3 每件费用是c[i],价值是w[i],求解将哪些物品放入背包
 4 使费用总和不超过背包容量且价值总和最大
 5 
 6 for(i=1; i<=n; ++i)
 7 for(j=0; j<=v; ++j)
 8 for(k=0; k*c[i]<=j; ++k)
 9     dp[i][j] = max(dp[i][j],dp[i-1][j-k*c[i]]+k*w[i]);
10 时间复杂度为O(V*∑n[i]);
11 另一种思想是二进制优化,时间复杂度为O(V*∑log(n[i]));
12 详见图片
13 */
14 #include <stdio.h>
15 #include <string.h>
16 int cash;
17 int n[11],dk[11];
18 int dp[1000000];
19 inline int max(const int &a, const int &b)
20 {
21     return a < b ? b : a;
22 }
23 void CompletePack(int cost)
24 {
25     for(int i=cost; i<=cash; ++i)
26         dp[i] = max(dp[i],dp[i-cost]+cost);
27 }
28 void ZeroOnePack(int cost)
29 {
30     for(int i=cash; i>=cost; --i)
31         dp[i] = max(dp[i],dp[i-cost]+cost);
32 }
33 void MultiplePack(int cnt, int cost)
34 {
35     if(cnt*cost >=cash)//如果第i种物品的费用总和超过背包容量,那么就是完全背包问题
36         CompletePack(cost);
37     else
38     {
39         int k = 1;//二进制拆分
40         while(k<cnt)
41         {
42             ZeroOnePack(cost*k);
43             cnt -=k;
44             k<<=1;
45         }
46         ZeroOnePack(cnt*cost);
47     }
48 }
49 int main()
50 {
51     int N,i,k,cnt,j;
52     while(scanf("%d%d",&cash,&N)!=EOF)
53     {
54         memset(dp,0,sizeof(dp));
55         for(i=1; i<=N; ++i)
56             scanf("%d%d",&n[i],&dk[i]);
57         for(i=1; i<=N; ++i)
58         {
59             MultiplePack(n[i],dk[i]);
60         }
61         printf("%d\n",dp[cash]);
62     }
63     return 0;
64 }

 

背包九讲之三(多重完全背包)

标签:

原文地址:http://www.cnblogs.com/justPassBy/p/4279124.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!