题意:中文的吧,飘过~
析:学过DP的都应该感觉到是动态规划吧,就是一个01背包问题,不同的是,这个题又加入一些新的条件,就是不满5元不能消费,过了5元即使超了也行(这个学校真不错,都可以预支),最后让你求剩下最少的金额(可以是负的),根据贪心我们应该知道最后一个买最贵的,为什么呢,如果在前面就先取了最贵的,那么剩余金额到快接近或者等于为5元时,然后再买一个肯定比不上,最后快接近或者等于5元时,再买那个最贵的剩下的少,当然还有一种情况就是买完所有的东西后,仍然大于或者等于5元,那么最后买最贵的和不是最后买结果是一样的,综上,我们应该最后买那个最贵的。
所以我们就先取出来5元,相当于是在m-5的背包中装物品,使其最大,后面就很easy了。
代码如下:
#include <iostream> #include <cstdio> #include <vector> #include <set> #include <queue> #include <iomanip> #include <cstring> #include <sstream> #include <algorithm> #include <map> #include <list> using namespace std; typedef long long LL; const int maxn = 1000 + 10; int a[maxn], d[maxn]; int main(){ int n, m; while(scanf("%d", &n), n){ int maxnn = -1, indx; for(int i = 1; i <= n; ++i){ scanf("%d", &a[i]); if(maxnn < a[i]){ maxnn = a[i]; indx = i; } //找一下最大的价格,最后再减掉 } scanf("%d", &m); if(m < 5){ printf("%d\n", m); continue; } //小于5,都不花费,直接输出结果 memset(d, 0, sizeof(d)); for(int i = 1; i <= n; ++i){ if(i == indx) continue; for(int j = m-5; j >= a[i]; --j) //保证最后价格大于等于5 d[j] = max(d[j], d[j-a[i]] + a[i]); //01背包 } printf("%d\n", m-d[m-5]-a[indx]); } return 0; }