背景:1——WA:卡上最低要求为5元才能消费的边界情况没有处理。
思路:首先判断卡上余额是否有五元,不是直接输出。然后,从卡里面拿出五元来买最大价值,剩下的钱尽可能用完就可以了。
学习:1.这里透露了一个基本问题:从n个数中选取m个数,使这m个数的和尽可能的接近k。这个体是把k看做背包的容量,把一个数的值既看做价值又看做体积,转化为01背包问题。
我的代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int value[1009],F[1001]; int sum(int i,int n){ int ok=0; for(;i < n;i++) ok+=value[i]; return ok; } int main(void){ int n,money,max_price=0,mp; while(~scanf("%d",&n),n){<span id="transmark"></span> max_price=0; for(int i=0;i < n;i++){ scanf("%d",&value[i]); if(value[i] > max_price){ mp=i; max_price=value[i]; } } value[mp]=0; // 最大单价的隔离出来 scanf("%d",&money); if (money-5 >= 0) money-=5; //卡上要保留5元钱,最低消费额为5元 else{ printf("%d\n",money); continue; } memset(F,0,sizeof(F)); for(int i=0;i < n;i++){ int min=max(value[i],money-sum(i,n)); //总价值减去,后面所有物品的总价值,一个常数的优化 for(int j=money;j >= min;j--) //注意这里是大于等于 F[j]=max(F[j],F[j-value[i]]+value[i]); //注意这里是当前背包容量j减去花费容量 } printf("%d\n",money+5-F[money]-max_price); } return 0; }
时间: 2024-11-08 15:10:44