第二次刷题。
之前刷题太功利了,现在刷题不为竞赛,只为更好的理解算法!
题意:给你w元钱,食堂里有n中菜,只要你确保卡里还有5元钱以上,那么你就可以买菜,不管价格是多少。问最多消费是多少。
思路:因为有5元钱这个限制,其实我们很难直接用背包来做。那么我们先考虑一下贪心的思路。价格最贵的菜,我肯定是想留在最后花5元去买了,这样一定是最有利的!
那么我们留下5元钱以后,剩下w-5元钱,就可以去随便买剩下的n-1个菜,只要钱够就行。所以这时我们就可以用背包来做了。
总结:先贪心转化为背包即可解决这题,这题的关键就是要进行贪心转化,想到这个还是有些难度的。
反思:为什么一开始想不到贪心转化呢? 原因应该是我拿到题目,知道这是背包的专题,所以没有分析这个题目的坑点,而是直接想要怎么背包。其实模拟一下这个过程,发现5元钱那个要求,只会对一个菜有用,所以先去掉这个菜,就没有5元钱这个限制了,就可以直接用背包了。做题之前模拟一下过程很重要!
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+9;
int a[maxn];
int dp[maxn];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int n;
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(a,a+n);
int W;
scanf("%d",&W);
if(W<5)
{
cout<<W<<endl;
continue;
}
memset(dp,0,sizeof(dp));
for(int i=0;i<n-1;i++)
{
for(int j=W-5;j>=a[i];j--)
{
dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
}
}
cout<<W-dp[W-5]-a[n-1]<<endl;
}
}