1 50 5 10 1 2 3 2 1 1 2 3 2 1 50 0
-45 32
当余额小于5的时候什么都买不了,直接输出余额,否则先用5买最贵的菜,然后转化为容量为m - 5的零一背包
状态转移方程是
f[i] = max{ f[i], f[i - price[i]] + price[i] }
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; int price[1005], dp[1005], sizedp = sizeof(dp); int n, m; int main() { while (~scanf("%d", &n) && n) { for (int i = 1; i <= n; i++) scanf("%d", &price[i]); scanf("%d", &m); if (m >= 5) { sort(price + 1, price + n + 1); int t = price[n]; //最贵的菜的价格 memset(dp, 0, sizedp); for (int i = 1; i <= n - 1; i++) { //用滚动数组求容量为m - 5的零一背包 for (int j = m - 5; j >= price[i]; j--) { if (dp[j - price[i]] + price[i] > dp[j]) dp[j] = dp[j - price[i]] + price[i]; } } printf("%d\n", m - t - dp[m - 5]); //注意最终解是dp[m - 5] } else { printf("%d\n", m); } } return 0; }