1 题目

http://acm.hdu.edu.cn/showproblem.php?pid=3591

题意:货币系统有 N 种不同面值的钱,每种钱的价值分别为 V1,V2,...,VN 一个人要买价值和为 T 的商品,他每种分别相应的带了 C1,C2,...,CN ,然后问你交易完成后所需要经手的钱币最少数目
思路:先对人进行多重背包,然后对售货员进行完全背包
答案其实和以前做的那题 背包超过容量的处理是一样的(uva 10819)
一直情况就是那个人所带的钱刚好凑成了 T ,那么就不需要找钱了,否则就需要找钱,相当于那个人支付了他所能付的超过 T 的钱 M,然后售货员找钱 M-T ,把这两者的经手的钱数加起来就行了
初始化的时候除了 dp[0]=0 之外,其它的都为 inf 表示 i 这个状态是可以由商品组合起来的
否则如果全部初始化为 0 的话,i 只能说是一个上界

1.2 题解

But Xiaoqian is a low-pitched girl , she wouldn’t like giving out more than 20000 once.一次不会付钱超过20000块。
背包容量是钱的价值,重量是钱的数目(每个钱币的重量都是1),求给出相同的钱的价值可以使用的最少(注意不是最大)的钱币数量。
动态规划求的是最小值。

对于主人公方用多重背包求,售后员方用完全背包求。 然后背包容量之差恰好等于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 多重背包+完全背包练习题相关推荐

  1. HDU 1248 寒冰王座(全然背包:入门题)

    HDU 1248 寒冰王座(全然背包:入门题) http://acm.hdu.edu.cn/showproblem.php?pid=1248 题意: 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票 ...

  2. POJ 3260 多重背包+完全背包

    前几天刚回到家却发现家里没网线 && 路由器都被带走了,无奈之下只好铤而走险尝试蹭隔壁家的WiFi,不试不知道,一试吓一跳,用个手机软件简简单单就连上了,然后在浏览器输入192.168 ...

  3. The Fewest Coins(多重背包+完全背包)

    The Fewest Coins(多重背包+完全背包) Farmer John has gone to town to buy some farm supplies. Being a very eff ...

  4. hdu 3535 AreYouBusy 经典混合背包

    借此机会,整理一下背包中的某几类问题: 物品分组,每组至少选一个: 这个时候 写法1:看别人博客,这样写省去了某些麻烦问题 达不到的dp值为-INF dp[i][j]=max(dp[i][j],max ...

  5. 动态规划总结(01背包 完全背包 多重背包)

    动态规划总结(01背包 完全背包 多重背包) 一.学习资料 1.UVA DP 入门专题 2.夜深人静写算法(二) - 动态规划 3.算法之动态规划 4.什么是动态规划?动态规划的意义是什么? 5.01 ...

  6. 动态规划之背包问题---01背包---完全背包---多重背包

    本篇博客是基于Carl大佬的刷题笔记 (代码随想录) 进行总结的 另外加入了我自己的一些整理,特此记录,以防遗忘 几种在面试中常见的背包,其关系如下: 通过这个图,可以很清晰分清这几种常见背包之间的关 ...

  7. 旅行商的背包(二进制优化多重+0/1背包枚举体积))

    旅行商的背包(二进制优化多重+0/1背包枚举体积)) 题目描述 小 S 坚信任何问题都可以在多项式时间内解决,于是他准备亲自去当一回旅行商.在出发之前,他购进了一些物品.这些物品共有 n n n 种, ...

  8. (背包dp) 背包N讲

    文章目录 前言 相关练习题 模板题 01背包 完全背包 多重背包 小数据范围 (可朴素暴力) 中等数据范围 (二进制优化) 大数据范围 (单调队列优化) 混合背包 二维费用背包 分组背包 有依赖的背包 ...

  9. 背包——完全背包Warcraft III(哈理工1053)

    *不了解01背包的同学请移步  http://blog.csdn.net/sm9sun/article/details/53235986 题目链接:http://acm.hrbust.edu.cn/i ...

最新文章

  1. 使用bitblt提高GDI+绘图的效率(转)
  2. win8安装msi出现提示2503 2502的错误代码
  3. Java第三章 类和对象3.1+3.2
  4. 如何使用C#自带的GDI+双缓冲类BufferedGraphics实现双缓冲功能
  5. linux 命令分号,linux命令之间的分号,, ||
  6. 前端学习(1431):ajax封装六
  7. windows 开启mysql日志记录_Windows下MySQL开启历史记录
  8. oracle数据库disable,Disable/Enable Oracle Database Vault
  9. c语言2维动态数组,如何创建一个动态2维数组?
  10. go语言 select
  11. mysql哪一款好用_用了这么多年MySql,这些好习惯你用过哪些
  12. java常见的定时任务
  13. [转载] python字典类方法
  14. armv6、armv7、armv7s、armv8、armv64及其i386、x86_64区别
  15. 网络安全信息收集的思路
  16. JavaScript事件函数
  17. 常量和常变量(const)
  18. 推荐几本学习Java的教材
  19. 少儿学编程系列---如何使用turtle画鸡蛋
  20. HTTP POST 请求工具类

热门文章

  1. OPPO 一脚踏入世界上最深的坑
  2. テクニカルアーティストについての記事をいくつか見つけました
  3. 三本学校组织学生去日本IT公司实习咋样?
  4. 初学者画动漫人物时画面很不自然?教你增加肤色的通透效果
  5. mask rcnn算法原理图_Mask_RCNN官方示例算法测试
  6. sql server2000安装挂起的解决办法
  7. 技术分享PPT整理(三):网页渲染流程
  8. python3 爬虫_Python3爬虫介绍
  9. 【N32G457 】基于RT-Thread和N32G457的CAN网关
  10. 视频怎么做成GIF表情包?教你两种简单好用的制作方法