杭电OJ 1114:Piggy-Bank

43 篇文章 0 订阅
15 篇文章 0 订阅

题目链接地址:http://acm.hdu.edu.cn/showproblem.php?pid=1114

这是一道完全背包问题,可以讲完全背包问题转换为01背包问题解,也可以直接求解。完全背包问题的状态转移方程为:f[i][v]=max{f[i-1][v],f[i][v-c[i]]+w[i]}。需要注意的是本题不是求最大值而是求最小值,所以初始化的时候要注意。

1、转化为01背包问题的代码:

#include<stdio.h>
#include<limits.h>
int main(){
	//freopen("1.txt","r",stdin);
	int T,E,F,N;
	int W[501],V[501];
	int nWeight[8000],nValue[8000],dp[10010]; //
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&E,&F);
		scanf("%d",&N);
		int index=0;
		for(int i=0;i<N;i++){
			scanf("%d%d",&V[i],&W[i]);
			int k=1;
			while(k*W[i]<=(F-E)){
				nWeight[index]=k*W[i];
				nValue[index++]=k*V[i];
				k*=2;
			}
		}
		dp[0]=0;
		for(int i=1;i<=F-E;i++)
			dp[i]=1000000001;
		for(int i=0;i<index;i++){
			for(int j=(F-E);j>=nWeight[i];j--){
				if(dp[j]>(dp[j-nWeight[i]]+nValue[i])){
					dp[j]=dp[j-nWeight[i]]+nValue[i];
				}
			}
		}
		if(dp[F-E]==1000000001)
			printf("This is impossible.\n");
		else
			printf("The minimum amount of money in the piggy-bank is %d.\n",dp[F-E]);
	}
	return 0;
}


2、直接利用完全背包问题的状态转移方程的解法:

#include<stdio.h>
const int INF=1000000001;
int main(){
	//freopen("1.txt","r",stdin);
	int T,E,F,N;
	int V[501],W[501],dp[10001];
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&E,&F);
		scanf("%d",&N);
		for(int i=0;i<N;i++)
			scanf("%d%d",&V[i],&W[i]);
		F=F-E;
		for(int i=1;i<=F;i++)
			dp[i]=INF;
		dp[0]=0;
		for(int i=0;i<N;i++){
			for(int j=W[i];j<=F;j++){
				if(dp[j]>dp[j-W[i]]+V[i])
					dp[j]=dp[j-W[i]]+V[i];
			}
		}
		if(dp[F]==INF)
			printf("This is impossible.\n");
		else
			printf("The minimum amount of money in the piggy-bank is %d.\n",dp[F]);
	}
	return 0;
}


关于3种背包问题的详细解法请参考:TankyWoo大神的帖子。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值