多重背包(二进制模板+普通解法)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=2191

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5
 6 using namespace std;
 7 const int MAX = 100 + 10;
 8 int V;
 9 int f[MAX],Price[MAX],Weight[MAX],Amount[MAX];
10 void OneZeorPage(int cost, int weight)
11 {
12     for(int i = V; i >= cost; i--)
13         f[i] = max(f[i], f[i - cost] + weight);
14 }
15 void CompletePage(int cost, int weight)
16 {
17     for(int i = cost; i <= V; i++)
18         f[i] = max(f[i], f[i - cost] + weight);
19
20 }
21 void multiplePage(int cost,int weight,int amount)
22 {
23     if(amount * cost >= V)
24     {
25         CompletePage(cost,weight);
26         return;
27     }
28     int k = 1;
29     while(k < amount)
30     {
31         OneZeorPage(k * cost, k * weight);
32         amount -= k;
33         k <<= 1;
34     }
35     if(amount > 0)
36         OneZeorPage(amount * cost, amount * weight);
37     return;
38 }
39 int main()
40 {
41     int n,m,t;
42     scanf("%d", &t);
43     while(t--)
44     {
45         scanf("%d%d", &n,&m);
46         for(int i = 1; i <= m; i++)
47             scanf("%d%d%d", &Price[i],&Weight[i],&Amount[i]);
48         memset(f,0,sizeof(f));
49         V = n;
50         for(int i = 1; i <= m; i++)
51             multiplePage(Price[i],Weight[i],Amount[i]);
52         printf("%d\n",f[n]);
53     }
54     return 0;
55 }

二进制优化

那为什么会有完全背包和01 背包的不同使用加判断呢?原因也很简单啊,当数据很大,大于背包的容纳量时,我们就是在这个物品中取上几件就是了,取得量时不知道的,也就理解为无限的啦,这就是完全背包啦,反而小于容纳量的就是转化为01背包来处理就是了,可以大量的省时间。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cstdio>
 5
 6 using namespace std;
 7 const int MAX = 100 + 10;
 8 int V;
 9 int f[MAX],Price[MAX],Weight[MAX],Amount[MAX];
10 int main()
11 {
12     int n,m,t;
13     scanf("%d", &t);
14     while(t--)
15     {
16         scanf("%d%d", &n,&m);
17         for(int i = 1; i <= m; i++)
18             scanf("%d%d%d", &Price[i],&Weight[i],&Amount[i]);
19         memset(f,0,sizeof(f));
20         V = n;
21         for(int i = 1; i <= m; i++)
22         {
23             for(int k = 1; k <= Amount[i]; k++)
24             {
25                 for(int j = V; j >= Price[i]; j--)
26                 {
27                     f[j] = max(f[j], f[j - Price[i]] + Weight[i]);
28                 }
29             }
30         }
31         printf("%d\n",f[n]);
32     }
33     return 0;
34 }

朴素的算法

时间: 2024-10-27 08:44:42

多重背包(二进制模板+普通解法)的相关文章

POJ 1014 Dividing 【DP 之 多重背包 / 二进制优化】

Language: Default Dividing Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 63647   Accepted: 16488 Description Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal

hdu1059 dp(多重背包二进制优化)

hdu1059 题意,现在有价值为1.2.3.4.5.6的石头若干块,块数已知,问能否将这些石头分成两堆,且两堆价值相等. 很显然,愚蠢的我一开始并想不到什么多重背包二进制优化```因为我连听都没有听过```不得不吐槽自己的知识面太窄```于是,我用了母函数写这题,母函数的做法并没有问题,但是由于这道题的数据很大,母函数轻轻松松就超时了,于是,我又很努力地在母函数循环的优化上面想出路,改改改,各种改之后依旧TLE,01背包的做法显然也是会超时的,DISCUSS里的母函数做法优化方式都是模上一个大

HDU 1059 多重背包+二进制优化

Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 16909    Accepted Submission(s): 4729 Problem Description Marsha and Bill own a collection of marbles. They want to split the collection

[多重背包+二进制优化]HDU1059 Dividing

题目链接 题目大意: 两个人要把一堆宝珠,在不能切割的情况下按照价值平分,他们把宝珠分成6种价值,每种价值的宝珠n个. n<=200000 思考: 首先如果加和下来的价值是一个偶数 那么还分毛啊,直接gg. 之后多重背包二进制优化 转换为 01背包. 我们可以把价值 同时当做宝珠的空间和价值. 那么我们现在要求的是 在 空间为一半的情况下,能否找到价值为 一半的情况. 1 #include <cstdio> 2 #include <algorithm> 3 #include

14年省赛---多重部分和问题(多重背包+二进制优化)

1210: F.多重部分和问题 时间限制: 1 Sec  内存限制: 64 MB提交: 18  解决: 14 题目描述 有n种不同大小的数字,每种各个.判断是否可以从这些数字之中选出若干使它们的和恰好为K. 输入 首先是一个正整数T(1<=T<=100)接下来是T组数据 每组数据第一行是一个正整数n(1<=n<=100),表示有n种不同大小的数字 第二行是n个不同大小的正整数ai(1<=ai<=100000)第三行是n个正整数mi(1<=mi<=100000

台州 OJ 2537 Charlie&#39;s Change 多重背包 二进制优化 路径记录

描述 Charlie is a driver of Advanced Cargo Movement, Ltd. Charlie drives a lot and so he often buys coffee at coffee vending machines at motorests. Charlie hates change. That is basically the setup of your next task. Your program will be given numbers

多重背包——二进制转化法

Learn from God LZW,worship... 多重背包(MultiplePack): 有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 这种背包问题与完全背包问题相似.对于第i种物品,可以取0件,1件,2件,……,n[i]件.可以把这种问题转化为01背包问题,对于取1,2,……,n[i]件各立一个物品,这样就可以用01背包的方法轻松解决.但是,当遇上强数据

HDU 2191 悼念512【多重背包+二进制优化】

大意分析: 多重背包,转化为01背包即可 可以用二进制进行优化 代码:(代码没有优化,下题是优化才可过的) 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 105; 7 8 int n, m, tot; 9 int p[2005], h[2005]; 10 int dp[maxn]; 11 int solv

POJ 1014 Dividing【多重背包+二进制优化】

大意: 价值1, 2, 3, ……, 6的物品分别a1, a2, ……, a5, a6件 问能否把这些物品分成两份,使其具有相同的价值(所有物品必须全部用上) 分析: 给个物品有多件,即多重背包 只要看能不能将这些物品拼成   总价值 的 一半就可以了 转化为01背包是用二进制优化,否则会超时 代码: 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std;

01背包模板、全然背包 and 多重背包(模板)

转载请注明出处:http://blog.csdn.net/u012860063 贴一个自觉得解说不错的链接:http://www.cppblog.com/tanky-woo/archive/2010/07/31/121803.html 模版就直接贴代码: 01背包模板: /* 01背包问题 01背包问题的特点是,">每种物品仅有一件.能够选择放或不放. 01背包问题描写叙述: 有N件物品和一个容量为V的背包. 第i件物品的重量是c[i],价值是w[i]. 求解将哪些物品装入背包可使这些物品