POJ 3260 多重背包+完全背包

  前几天刚回到家却发现家里没网线 && 路由器都被带走了,无奈之下只好铤而走险尝试蹭隔壁家的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]<=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 }

  因为一开始没用到need数组所以调试了一会儿,anyway,人生第一道混合背包的AC,值得纪念,背包问题,继续进取中~~

时间: 2024-08-05 02:46:27

POJ 3260 多重背包+完全背包的相关文章

poj 1276(多重背包)

Cash Machine Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 31525   Accepted: 11333 Description A Bank plans to install a machine for cash withdrawal. The machine is able to deliver appropriate @ bills for a requested cash amount. The m

poj 1384 Piggy-Bank(完全背包)

http://poj.org/problem?id=1384 Piggy-Bank Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 7900 Accepted: 3813 Description Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. The main income f

POJ 3628 Bookshelf 2 (01背包)

Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7496   Accepted: 3451 Description Farmer John recently bought another bookshelf for the cow library, but the shelf is getting filled up quite quickly, and now the only available

HDU 3591 The trouble of Xiaoqian(多重背包+01背包)

HDU 3591 The trouble of Xiaoqian(多重背包+01背包) http://acm.hdu.edu.cn/showproblem.php?pid=3591 题意: 有一个具有n种货币的货币系统, 每种货币的面值为val[i]. 现在小杰手上拿着num[1],num[2],-num[n]个第1种,第2种-第n种货币去买价值为T(T<=20000)的商品, 他给售货员总价值>=T的货币,然后售货员(可能,如果小杰给的钱>T, 那肯定找钱)找钱给他. 售货员每次总是用

POJ 3181 Dollar Dayz(完全背包+简单高精度加法)

POJ 3181 Dollar Dayz(完全背包+简单高精度加法) http://poj.org/problem?id=3181 题意: 给你K种硬币,每种硬币分别是1美元,2美元-K美元且可以无限使用,问你用上面K种硬币构成n美元的话有多少种方法? 分析: 本题是一道明显的完全背包问题, 不过本题还可以换一种方法来看: 整数n由前K个自然数构造, 一共有多少种方法? (虽然本题要用到高精度加法, 但是很简单, 不要被吓到哦) 首先是DP部分: 令dp[i][j]==x 表示由前i种硬币构成j

POJ3260——The Fewest Coins(多重背包+完全背包)

The Fewest Coins DescriptionFarmer John has gone to town to buy some farm supplies. Being a very efficient man, he always pays for his goods in such a way that the smallest number of coins changes hands, i.e., the number of coins he uses to pay plus

POJ 1745 【0/1 背包】

题目链接:http://poj.org/problem?id=1745 Divisibility Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13431   Accepted: 4774 Description Consider an arbitrary sequence of integers. One can place + or - operators between integers in the sequen

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

01背包 有n种不同的物品,每种物品分别有各自的体积 v[i],价值 w[i]  现给一个容量为V的背包,问这个背包最多可装下多少价值的物品. 1 for(int i = 1; i <= n; i++) 2 for(int j = V; j >= v[i]; j--) 3 dp[j] = max(dp[j], dp[j-v[i]]+w[i]); //dp[V]为所求 完全背包 01背包每种物品只能取一个, 完全背包即物品不记件数,可取多件. 1 for(int i = 1; i <= n

ZOJ 3164 Cookie Choice 分组背包 混合背包

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3181 题意: 就是混合背包加分组背包,有的物品是01背包,有的是多重背包,有的是完全背包,同时物品还有不超过8组的分组,如果在同一组则最多只能选一种.问能不能恰好地用掉D的容量,并且使所获价值最大. 分析: 开始的想法是多开一个下标,先把没有分组的做了,在0的下标,然后分组分别在组号的下标里按顺序处理,是什么背包就用什么做法,不过一直WA,对拍小数据大数据都没啥问题(可能随机