hdu 3591 多重背包+完全背包练习题
1 题目
http://acm.hdu.edu.cn/showproblem.php?pid=3591
1.2 题解
对于主人公方用多重背包求,售后员方用完全背包求。 然后背包容量之差恰好等于T的情况中取使用硬币数目最少的。
ans = INT_MAX;
for(i=T;i<20001;i++)
ans = min(ans,dp[i]+dp[i-T])
2 AC代码
2,.1 版本一(超时了)
#include<iostream>
#include<algorithm>
#include<limits.h>
using namespace std;int inf = 20001; //足够大的数int v = 20000; //背包的容量//处理一件01背包中的物品
void ZeroOnePack(int dp[], int cost, int weight)
{for (int i = v; i >= cost; i--)//descenddp[i] = min(dp[i], dp[i - cost] + weight);
}//deal with one item
void CompletePack(int dp[], int cost, int weight)
{for (int i = cost; i <= v; i++)dp[i] = min(dp[i], dp[i - cost] + weight);
}//deal with one item
void MultiplePack(int dp[], int cost, int weight, int number)
{if (cost*number >= v) //注意等于号{//物品足够多转化为完全背包CompletePack(dp, cost, weight);return;}int k = 1;while (k < number)//二进制拆分{ZeroOnePack(dp, k*cost, k*weight);number -= k;k << 2;}ZeroOnePack(dp, cost*number, weight*number);
}int main(int)
{int dp[20002], dp2[20002];//背包容量是钱的价值,重量是钱的数目(每个钱币的重量都是1),求给出相同的钱的价值可以使用的最少(注意不是最大)的钱币数量//But Xiaoqian is a low-pitched girl , she wouldn’t like giving out more than 20000 once.一次不会付钱超过20000块int N, T, v[101], c[101], cnt = 0, i, j, ans;while (scanf("%d %d", &N, &T) != EOF && (N != 0 || T != 0)){cnt++;if (N == 0 || T == 0){printf("Case %d: %d\n", cnt, 0);continue; //这里打成continue会卡在那里一直等待输入,报time limit exceeded}for (i = 1; i <= N; i++)scanf("%d", &v[i]);for (i = 1; i <= N; i++)scanf("%d", &c[i]);//初始化for (i = 0; i<20002; i++)dp[i] = inf, dp2[i] = inf; //这里的初值只能设置为足够大,而不能是INT_MAX,否则dp[i - cost] + weight会由于溢出变成负数!!!dp[0] = dp2[0] = 0; //注意dp[0]是有意义的,要单独初始化!!!//背包for (i = 1; i<=N; i++) //这里的上界应该是物品的数量CompletePack(dp2, v[i], 1);for (i = 1; i<=N; i++)//这里的上界应该是物品的数量MultiplePack(dp, v[i], 1, c[i]);ans = INT_MAX;int t = inf;for (i = T; i<20001; i++)if (ans > dp[i] + dp2[i - T]){ans = dp[i] + dp2[i - T];t = i;}!(dp[t] == inf || dp[t - T] == inf) ? printf("Case %d: %d\n", cnt, ans) : printf("-1\n");}return 0;
}
/**
3 70
5 25 50
5 2 1
0 0**/
15893603 | 2015-12-18 14:19:58 | Time Limit Exceeded | 3591 | 1000MS | 1664K | 2186 B | G++ | aaaaaaaaaaaaalc |
说实话不明白这个代码为什么会超时,这个代码跟下面一个版本本质上是一样的。
2.2 版本二
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e2 + 10;//110
const int maxm = 2e4 + 10; //20010
const int INF = 1e8;
int c[maxn], v[maxn], f[maxm], g[maxm];
int main()
{int n, m, tt = 0;while (scanf("%d%d", &n, &m) != EOF){if (n == 0 && m == 0)break;int i, j, k;for (i = 0; i<n; i++)scanf("%d", &v[i]);for (i = 0; i<n; i++)scanf("%d", &c[i]);for (i = 1; i <= 20000; i++){g[i] = f[i] = INF;}f[0] = g[0] = 0;//完全背包for (i = 0; i<n; i++){for (j = v[i]; j <= 20000; j++)g[j] = min(g[j], g[j - v[i]] + 1);}//多重背包for (i = 0; i<n; i++){if (v[i] * c[i] >= 20000){for (j = v[i]; j <= 20000; j++)f[j] = min(f[j], f[j - v[i]] + 1);continue;}for (k = 1; k<c[i]; k = k * 2){for (j = 20000; j >= v[i] * k; j--)f[j] = min(f[j], f[j - v[i] * k] + k);c[i] -= k;}for (j = 20000; j >= c[i] * v[i]; j--)f[j] = min(f[j], f[j - v[i] * c[i]] + c[i]);}int ans = INF;for (i = m; i <= 20000; i++)ans = min(ans, f[i] + g[i - m]);if (ans == INF)ans = -1;printf("Case %d: %d\n", ++tt, ans);}return 0;
}
15893097 | 2015-12-18 13:14:08 | Accepted | 3591 | 46MS | 1716K | 1344 B | G++ | aaaaaaaaaaaaalc |
3 总结
目前对dp[]数组初始化对程序的影响过程不算很清楚。
3.2 初始化问题
注意dp[0]是有意义的,要单独初始化!!!
dp[i] = inf, dp2[i] = inf; //这里的初值只能设置为足够大,而不能是INT_MAX,否则dp[i - cost] + weight会由于溢出变成负数!!!
hdu 3591 多重背包+完全背包练习题相关推荐
- HDU 1248 寒冰王座(全然背包:入门题)
HDU 1248 寒冰王座(全然背包:入门题) http://acm.hdu.edu.cn/showproblem.php?pid=1248 题意: 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票 ...
- POJ 3260 多重背包+完全背包
前几天刚回到家却发现家里没网线 && 路由器都被带走了,无奈之下只好铤而走险尝试蹭隔壁家的WiFi,不试不知道,一试吓一跳,用个手机软件简简单单就连上了,然后在浏览器输入192.168 ...
- The Fewest Coins(多重背包+完全背包)
The Fewest Coins(多重背包+完全背包) Farmer John has gone to town to buy some farm supplies. Being a very eff ...
- hdu 3535 AreYouBusy 经典混合背包
借此机会,整理一下背包中的某几类问题: 物品分组,每组至少选一个: 这个时候 写法1:看别人博客,这样写省去了某些麻烦问题 达不到的dp值为-INF dp[i][j]=max(dp[i][j],max ...
- 动态规划总结(01背包 完全背包 多重背包)
动态规划总结(01背包 完全背包 多重背包) 一.学习资料 1.UVA DP 入门专题 2.夜深人静写算法(二) - 动态规划 3.算法之动态规划 4.什么是动态规划?动态规划的意义是什么? 5.01 ...
- 动态规划之背包问题---01背包---完全背包---多重背包
本篇博客是基于Carl大佬的刷题笔记 (代码随想录) 进行总结的 另外加入了我自己的一些整理,特此记录,以防遗忘 几种在面试中常见的背包,其关系如下: 通过这个图,可以很清晰分清这几种常见背包之间的关 ...
- 旅行商的背包(二进制优化多重+0/1背包枚举体积))
旅行商的背包(二进制优化多重+0/1背包枚举体积)) 题目描述 小 S 坚信任何问题都可以在多项式时间内解决,于是他准备亲自去当一回旅行商.在出发之前,他购进了一些物品.这些物品共有 n n n 种, ...
- (背包dp) 背包N讲
文章目录 前言 相关练习题 模板题 01背包 完全背包 多重背包 小数据范围 (可朴素暴力) 中等数据范围 (二进制优化) 大数据范围 (单调队列优化) 混合背包 二维费用背包 分组背包 有依赖的背包 ...
- 背包——完全背包Warcraft III(哈理工1053)
*不了解01背包的同学请移步 http://blog.csdn.net/sm9sun/article/details/53235986 题目链接:http://acm.hrbust.edu.cn/i ...
最新文章
- 使用bitblt提高GDI+绘图的效率(转)
- win8安装msi出现提示2503 2502的错误代码
- Java第三章 类和对象3.1+3.2
- 如何使用C#自带的GDI+双缓冲类BufferedGraphics实现双缓冲功能
- linux 命令分号,linux命令之间的分号,, ||
- 前端学习(1431):ajax封装六
- windows 开启mysql日志记录_Windows下MySQL开启历史记录
- oracle数据库disable,Disable/Enable Oracle Database Vault
- c语言2维动态数组,如何创建一个动态2维数组?
- go语言 select
- mysql哪一款好用_用了这么多年MySql,这些好习惯你用过哪些
- java常见的定时任务
- [转载] python字典类方法
- armv6、armv7、armv7s、armv8、armv64及其i386、x86_64区别
- 网络安全信息收集的思路
- JavaScript事件函数
- 常量和常变量(const)
- 推荐几本学习Java的教材
- 少儿学编程系列---如何使用turtle画鸡蛋
- HTTP POST 请求工具类