HDU 2546 饭卡

本文详细解析了01背包问题的解决方法,并通过一个具体的编程实例进行说明。针对不同情况,如金额小于5元、等于5元及大于5元时的处理方式进行了阐述。对于大于5元的情形,采用了01背包算法进行求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、01背包问题,可以参考HDU 2602 Bone Collector,类似其变形

2、以5元为边界,小于5元的直接输出原卡上钱;恰好用到卡上剩余5元时,最后一道菜点最贵的,那么除去5元以外的钱可以相当于一个背包,除去最贵以外的菜可以当做装入背包的东西

3、开在外面的数组默认为0,因为忘记循环之后数组值会变,缺少循环内置零语句,一直WA

4、忘记自己开的二维数组(有i-1),循环从0开始,又一直WA

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

int dp[1010][1010];
int val[1010];

int main()
{
	int n,m;
	while(cin>>n && !(n==0)) {
		for(int i=1;i<=n;i++) {
			cin>>val[i];
		}
		cin>>m;
		sort(val+1,val+n+1);
		int mx=val[n];          //输入并对价值排序找到最大值
		
		if(m<5)                 //小于5的情况
		{
			cout<<m<<endl;
		}
		else if(m==5)           //等于5的情况
		{
			cout<<m-mx<<endl;
		}
		else if(m>5)            //01背包的实现
		{
			//因为忘记dp数组循环之后就不为0了,忘记写这个循环置零,一直WA
			memset(dp,0,sizeof(dp));    
			
			int i,j;
			for(i=1;i<n;i++) {
				for(j=0;j<=m-5;j++) {
					if(val[i]<=j) {
						dp[i][j]=max(dp[i-1][j],dp[i-1][j-val[i]]+val[i]);
					}else{
						dp[i][j]=dp[i-1][j];    //这里有i-1,所以i不能从0开始
					}
				}
			}
			cout<<m-dp[n-1][m-5]-mx<<endl;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值