前几天刚回到家却发现家里没网线 && 路由器都被带走了,无奈之下只好铤而走险尝试蹭隔壁家的WiFi,不试不知道,一试吓一跳,用个手机软件简简单单就连上了,然后在浏览器输入192.168.1.1就能看到他的路由器的一切信息,包括密码,然后打开笔记本……好了,废话不多说,能连上网后第一时间当然是继续和队友之前约好的训练了。

  今天翻看到之前落下的一道混合背包题目,然后在草稿本上慢慢地写递推方程,把一些细节细心地写好…(本来不用太费时间的,可是在家嘛,一会儿妈走来要我教她玩手机,一会儿有一个亲戚朋友来……简直无语了,程序猿最讨厌被人打断的!虽说我不是码农)然后,这道题,细心分析后,发现它是多重背包+完全背包的。

  首先,可以先顺着推出 John手中的coin能拼凑出的币值的最小币数,即设dp[i][j]为前 i 种coin凑出币值 j 时需要的最小币数,很明显,dp[i][j]= min(dp[i-1][j], dp[i][j-coin[i]]+1) 的递推方程很容易想到,但是,这个方程在使用前需要满足很多情况,具体的细节就看代码了(全部都进行了空间优化,其中need数组表示前 i 种coin凑出币值 j 需要的最小币数时,需要的coin[i]的数量),因为之前看过《挑战》中多重背包的实现,所以这个稍微变化一下也不是很难了。

  然后,到了收银员找币时的情况,因为题目中说了她会提供无限的零钱,所以此时就是完全背包了,注意好计算顺序即可:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long LL;
 6 const int maxn= 10000;
 7
 8 int dp[maxn+3], coin[103],num[103], need[maxn+3];
 9
10 int main(){
11     int n,t,i,j;
12     while(~scanf("%d%d",&n,&t)){
13         for(i=1; i<=n; ++i)
14             scanf("%d",coin+i);
15         for(i=1; i<=n; ++i)
16             scanf("%d",num+i);
17         memset(dp,-1,sizeof(dp));
18         dp[0]= 0;
19         for(i=1; i<=n; ++i){
20             memset(need,0,sizeof(need));
21             for(j=0; j<=maxn; ++j)
22                 if(j>=coin[i]&& dp[j-coin[i]]!= -1 && need[j-coin[i]]<num[i]){
23                     if(dp[j]== -1 || dp[j]> dp[j-coin[i]]+1){
24                         dp[j]= dp[j-coin[i]]+1;
25                         need[j]= need[j-coin[i]]+1;
26                     }
27                 }
28         }
29         for(i=1; i<=n; ++i)
30             for(j=maxn-coin[i]; j>=0; --j)
31                 if(dp[j+coin[i]]!= -1){
32                     if(dp[j]== -1)    dp[j]= dp[j+coin[i]]+1;
33                     else    dp[j]= min(dp[j],dp[j+coin[i]]+1);
34                 }
35         printf("%d\n",dp[t]);
36     }
37     return 0;
38 }

View Code

  因为一开始没用到need数组所以调试了一会儿,然后今早起来想了想发现昨晚写的need数组有问题,不知是数据弱还是怎么的也能过,改了下后提交发现:

  竟然排到了16名,第一次这么前。

  后来又想了想,dp数组如果用INF而不是-1来作为凑不出币值 j 的标记的话,代码会更简单一些:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long LL;
 6 const int INF= 0x3fffffff;
 7 const int maxn= 10000;
 8
 9 int dp[maxn+3], coin[103],num[103], need[maxn+3];
10
11 int main(){
12     int n,t,i,j;
13     while(~scanf("%d%d",&n,&t)){
14         for(i=1; i<=n; ++i)
15             scanf("%d",coin+i);
16         for(i=1; i<=n; ++i)
17             scanf("%d",num+i);
18         for(j=1; j<=maxn; ++j)
19             dp[j]= INF;
20         dp[0]= 0;
21         for(i=1; i<=n; ++i){
22             memset(need,0,sizeof(need));
23             for(j=0; j<=maxn; ++j)
24                 if(j>=coin[i] && need[j-coin[i]]<num[i]){
25                     if(dp[j]> dp[j-coin[i]]+1){
26                         dp[j]= dp[j-coin[i]]+1;
27                         need[j]= need[j-coin[i]]+1;
28                     }
29                 }
30         }
31         for(i=1; i<=n; ++i)
32             for(j=maxn-coin[i]; j>=0; --j)
33                 dp[j]= min(dp[j],dp[j+coin[i]]+1);
34         printf("%d\n",dp[t]==INF? -1:dp[t]);
35     }
36     return 0;
37 }

View Code

  虽然比起上一个慢了点可以忽略不计的时间:

  anyway,人生第一道AC掉的混合背包,值得纪念,背包问题,继续进取中~~

转载于:https://www.cnblogs.com/Newdawn/p/4269014.html

POJ 3260 多重背包+完全背包相关推荐

  1. 【题目记录】——POJ 3260 The Fewest Coins 混合背包

    POJ 3260 The Fewest Coins 题目地址[POJ 3260 The Fewest Coins] 题意:John要去买价值为m的商品. 现在的货币系统有n种货币,对应面值为val[1 ...

  2. 动态规划 背包问题小结 0-1背包(采药 九度第101题) 完全背包(Piggy-Bank POJ 1384) 多重背包(珍惜现在,感恩生活 九度第103题)

    本小结介绍0-1背包.完全背包以及多重背包问题 记忆要点: 0-1背包:二维数组情况下,顺序遍历体积或者倒序均可以                降维情况下需倒序遍历体积 完全背包:数组降维+顺序遍历 ...

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

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

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

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

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

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

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

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

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

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

  8. (背包dp) 背包N讲

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

  9. 动态规划_背包问题(01背包 完全背包)

    背包问题-多种物品 重量不同 价值不同. 你可以取最多重量不超过W的物品,问最大价值为多少? 01背包 01背包 指的是 有N个物品 每个物品的重量为W[ i ],价值为V[ i ],(每个物品只有一 ...

最新文章

  1. 海归技术大佬:硅谷科技公司到底牛在哪里?讲透“奈飞文化”8个原则!
  2. java jar log4j_java项目打包成可执行jar用log4j将日志写在jar所在目录操作
  3. java技术专家学习路线图_向Java最佳专家的全球专家学习Java
  4. 【LeetCode笔记】494. 目标和(Java、动态规划、背包问题、滚动数组)
  5. makefile从无到有
  6. 英文拼写及语法检查软件
  7. 9.UNIX 环境高级编程--进程关系
  8. java打包-exe文件-最终以setup形式发布的解决之道
  9. web前端课程设计:个人博客网站设计——个人博客(6页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 web前端设计与开发期末作品
  10. Http错误码从1 到5 详解
  11. php 微信公众号登录,PHP 实现微信公众号网页授权登录
  12. 青果信息系统操作问题
  13. 算法图解之狄克斯特拉算法实现
  14. 音频转换成mp3格式的步骤
  15. Linux NIS服务
  16. ubuntu多屏协同,在电脑上操作手机
  17. 风影导航网站源码v1.0 带后台
  18. mysql 垃圾_垃圾mysql pipelin
  19. 高等数学期末总复习 DAY 2.判断间断点类型 零点、
  20. 逆水寒显示连接服务器失败,逆水寒脚本封号吗地下城fc提示连接服务器失败

热门文章

  1. mysql 使用真正的utf-8编码
  2. oracle求某个数的阶乘,Oracle SQL实现阶乘的几个方法
  3. Python游戏开发:最强大脑第一关,数字华容道
  4. mysql数据库计划是什么_计划备份mysql数据库
  5. tcp 测试工具_6款免费网络延迟测试工具
  6. numpy的深复制与浅复制的区别_浅谈数据备份与复制对于企业用户的区别
  7. 在 Ubuntu 上通过命令行改变 Linux 系统语言
  8. 教你两种python selenium保存图片的方法
  9. 【Java】LeetCode 232. 用栈实现队列
  10. 用C语言实现三子棋游戏(附上思路+项目展示+源代码)