动态规划 完全背包问题 Piggy-Bank_67

【完全背包问题】
是对0-1背包问题的扩展,每种物品不只可以取一件,而是可以选择多件,每种物品的数量均为无限个。
将情况分为是否放入第i件物品两种:
(1)不放,dp[i][j]=dp[i-1][j]
(2)放,dp[i][j]=dp[i][j-w[i]]+v[i](因为第i件物品仍然可取)
优化为一维数组:dp[j]=max(dp[j],dp[j-w[i]]+v[i])
注:每次更新时,需要正序地遍历所有j的值,才能保证在确定dp[j]的值时,dp[j-w[i]]的值已被修改(因为是第i层不再是第i-1层)

Piggy-Bank
题意:
ACM在做任何事情之前,必须编制预算以获得必要的财政经费支持,而财政经费的来源则来自“不可逆转的束缚货币”(Irreversibly Bound Money,IBM)。这一做法的思想很简单。某个ACM成员只要有一点零钱,他就要把所有的硬币都扔进一个储蓄罐。如您所知,这个过程是不可逆的,如果不打破储蓄罐的话,硬币就不能被取出。在足够长的时间之后,储蓄罐里就会有足够的钱来支持所有需要进行的工作。
但是储蓄罐有一个大问题,就是不能确定里面有多少钱。这就有可能在我们把储蓄罐打碎之后,结果却发现钱不够。我们希望能够避免这种情况,唯一可能的方法就是称一下储蓄罐的重量,然后试着猜测里面有多少硬币。本题设定,我们能够精确地确定储蓄罐的重量,并且我们知道每一种硬币的重量。本题需要确定在储蓄罐里可以保证有的最低总金额。请您找出最坏的情况,确定储蓄罐内的最小的现金量。我们需要您的帮助,不要过早地打碎储蓄罐。

输入
输入给出T个测试用例。在输入的第一行给出测试用例的数目T。每个测试用例的第一行给出两个整数E和F,表示空的储蓄罐和装满硬币的储蓄罐的重量,这两个重量均以克为单位。储蓄罐的重量不会超过10公斤,也就是说,1 <= E <= F <= 10000。在测试用例的第二行给出一个整数N(1 <= N <= 500),给出在给定的货币体系中硬币的种类数量。接下来的N行,每行给出两个整数P和W(1 <= P <= 50000, 1 <= W <= 10000)表示一种硬币,P是该种硬币的面值,W是该种硬币的重量,单位是克。

输出
对于每个测试用例,输出一行。该行输出“The minimum amount of money in the piggy-bank is X.”,其中X是给定硬币总重量,储蓄罐内可以达到的最小金额。如果对于给出的硬币重量,无法计算出储蓄罐内的最小金额,则输出一行“This is impossible.”。

示例:
输入
3
10 110
2
1 1
30 50
10 110
2
1 1
50 30
1 6
2
10 3
20 4

输出
The minimum amount of money in the piggy-bank is 60.
The minimum amount of money in the piggy-bank is 100.
This is impossible.

#include<bits/stdc++.h>
using namespace std;
const int MAXN=10000;
const int INF=INT_MAX/10;
//完全背包问题,求最小值
//完全背包允许放多件物品 
int v[MAXN];//价值
int w[MAXN];//重量 
int dp[MAXN];

int main(){
	int c,n;
	int number;
	cin>>number;
	while(number--){
		int e,f;
		cin>>e>>f;
		int c=f-e;//背包容量 
		cin>>n;
		for(int i=0;i<n;i++){
			cin>>v[i]>>w[i];
		}
		dp[0]=0;
		for(int i=1;i<=c;i++){
			dp[i]=INF;//初始化
			//循环c次,转换为一维,因为后面要用到
			//因为在整个二维的表格中,前面的都一样
			//只需要最后的一个元素,所以其他层的元素不用考虑
		}
		for(int i=0;i<n;i++){
			for(int j=w[i];j<=c;j++){
				//之所以是顺序,是因为需要dp[j-w[i]]是第i层更新后的不再是第i-1层更新的 
				dp[j]=min(dp[j],dp[j-w[i]]+v[i]);
			}
		}
		if(dp[c]==INF){
			cout<<"This is impossible."<<endl;
		}
		else{
			cout<<"The minimum amount of money in the piggy-bank is "<<dp[c]<<"."<<endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江星竹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值