HDU2546 01背包

思路:

       因为是要求余额m的最小值,但是当m<5的时候就不能刷卡了。所以,要使m最小,最后所减去的数一定是最大的。所以先排序,然后在剩下的数字中寻找最接近m-5的一组数字,用bool dp[i][j]来保存,当dp = 1的时候,说明能访问到了即可。然后不要忘了最后单独的判断m刚开始就小于5.


然后还有这道题学会了一点,完全背包问题和01背包问题递推的方向^ ^



#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int maxn = 1000 + 10; const int inf = 0x3f3f3f3f; int n, mey; int meal[maxn]; int dp[1005][1005]; void solve(){ memset(dp, 0, sizeof(dp)); sort(meal, meal + n); int w = mey - 5; int res = 0; for (int i = 0; i < n; i++) dp[i][0] = 1; for (int i = 0; i < n - 1; i++){ for (int j = w; j >= meal[i]; j--){ if (dp[i][j - meal[i]] || dp[i][j]){ dp[i + 1][j] = 1; res = max(res, j); } } } printf("%d\n", w - res + 5 - meal[n - 1]); } int main(){ while(scanf("%d", &n) && n){ int sum = 0; memset(meal, 0, sizeof(meal)); for (int i = 0; i < n; i++){ scanf("%d", &meal[i]); // sum += meal[i]; } scanf("%d", &mey); if (mey < 5){ printf("%d\n", mey); continue; } solve(); } return 0; } </cmath></algorithm></cstring></cstdio>

你可能感兴趣的:(HDU2546 01背包)