1 50 5 10 1 2 3 2 1 1 2 3 2 1 50 0
-45 32
还是01背包问题,只是题目有个条件——钱数小于5的时候,不能买东西。这点注意一下。
如果初始钱数就小于5,则不买任何东西,直接输出当前钱数。
如果初始钱数大于等于5,则先把那5块腾出来买最贵的东西,然后对剩余的物品用01背包的方法就行了。
代码如下:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int main() { int n,v; int c[1111]; int dp[1111]; while (~scanf ("%d",&n) && n) { memset (dp,0,sizeof (dp)); for (int i = 1 ; i <= n ; i++) scanf ("%d",&c[i]); scanf ("%d",&v); if (v < 5) //特判一下 { printf ("%d\n",v); continue; } sort (c + 1 , c + n + 1); for (int i = 1 ; i < n ; i++) { for (int j = v - 5 ; j >= c[i] ; j--) //留出5块钱买最贵的 { dp[j] = max (dp[j] , dp[j-c[i]] + c[i]); } } printf ("%d\n",v - dp[v-5] - c[n]); } return 0; }