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

题目地址: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 }
时间: 2024-11-02 17:46:24

背包九讲之三(多重完全背包)的相关文章

背包九讲之多重背包

背包九讲原文: 题目 有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本算法 这题目和完全背包问题很类似.基本的方程只需将完全背包问题的方程略微一改即可,因为对于第i种物品有n[i]+1种策略:取0件,取1件……取n[i]件.令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值,则有状态转移方程: f[i][v]=max{f[i-1][v-k*c[i]]

悼念512汶川大地震遇难同胞――珍惜现在,感恩生活(背包九讲_多重背包)

悼念512汶川大地震遇难同胞――珍惜现在,感恩生活Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description 急!灾区的食物依然短缺! 为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价

Big Event in HDU(背包九讲_多重背包转01背包)

Big Event in HDUCrawling in process... Crawling failed Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you

多重背包问题(来源:背包九讲)

问题: 有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本算法: 这题目和全然背包问题非常类似.主要的方程仅仅需将全然背包问题的方程稍微一改就可以,由于对于第i种物品有n[i]+1种策略:取0件,取1件--取n[i]件.令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值,则有状态转移方程:f[i][v]=max{f[i-1][v-k*c[i]]+k*w

二维费用背包问题(背包九讲)

------------------------------------------ 前言: 对于一些背包问题,重点还是在于如何找出"背包容量"和"各种代价",以及价值,如此问题便迎刃而解了.下午 打篮球居然下冰雹了,悲催了.... ------------------------------------------ 问题: 二维费用的背包问题是指:对于每件物品,具有两种不同的费用:选择这件物品必须同时付出这两种代价:对于每种代价都有 一个可付出的最大值(背包容量)

转载:《背包九讲》

<背包九讲> P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}. 这个方程非常重要,基

转载DD大神背包九讲

dd大牛的<背包九讲> P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放. 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值.则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}. 这个方程非

混合三种背包问题(背包九讲)

问题: 如果将P01.P02.P03混合起来.也就是说,有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包).应该怎么求解呢? 01背包与完全背包的混合: 考虑到在P01和P02中给出的伪代码只有一处不同,故如果只有两类物品:一类物品只能取一次,另一类物品可以取无限次,那么只需在对每个物品应用转移方程时,根据物品的类别选用顺序或逆序的循环即可,复杂度是O(VN).伪代码如下: for i=1..N if 第i件物品属于01背包 for v

背包九讲(转载)

转载 背包问题 //0 1背包 #include<iostream> #include<stdio.h> #include<string.h> using namespace std; int main() { int i,j,n,v,f[1100],w[1100],p[1100]; scanf("%d",&t); while(t--) { memset(f,0,sizeof(f)); scanf("%d%d",&