题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2546
这是一个变形的01背包问题,首先如果金额小于5元,剩余金额不变,为已有金额。如果大于等于5元
我们先用5元买最贵的菜。然后用剩下的钱买其他的菜这时就是一个典型的01背包问题了;
求出最大的花费,然后用总金额减去最大的花费即为剩余金额。
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define INF 0xfffffff #define N 1005 int a[N], dp[N][N]; int main() { int n, m; while(scanf("%d", &n), n) { for(int i=1; i<=n; i++) scanf("%d", &a[i]); scanf("%d", &m); if(m<5) { printf("%d ", m); continue; } m-=5; sort(a+1, a+n+1); for(int i=1; i<n; i++) { for(int j=1; j<=m; j++) { dp[i][j] = dp[i-1][j];///千万不能忘的; if(j>=a[i]) dp[i][j] = max(dp[i-1][j], dp[i-1][j-a[i]]+a[i]); } } printf("%d ", m+5-dp[n-1][m]-a[n]); } return 0; }
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define INF 0xfffffff #define N 1005 int a[N], dp[N]; int main() { int n, m; while(scanf("%d", &n), n) { memset(a, 0, sizeof(a)); memset(dp, 0, sizeof(dp)); for(int i=1; i<=n; i++) scanf("%d", &a[i]); scanf("%d", &m); if(m<5) { printf("%d ", m); continue; } m-=5; sort(a+1, a+n+1); for(int i=1; i<n; i++) { for(int j=m; j>=a[i]; j--) { dp[j] = max(dp[j], dp[j-a[i]]+a[i]); } } printf("%d ", m+5-dp[m]-a[n]); } return 0; }