题意:给你n种面值的钱,告诉你每种面值钱的面值和个数,问能凑出最大的不大于m的钱数是多少。
解法:多重背包。我觉得直接多重背包转01应该会T……又懒得二进制搞……用了POJ1472的思路搞了一下……
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define LL long long using namespace std; bool dp[100005]; int used[100005]; struct node { int val, num; }money[15]; int main() { int n, m; while(~scanf("%d%d", &m, &n)) { memset(dp, 0, sizeof dp); int ans = 0; for(int i = 1; i <= n; i++) scanf("%d%d", &money[i].num, &money[i].val); dp[0] = true; for(int i = 1; i <= n; i++) { memset(used, 0, sizeof used); for(int j = 1; j <= m; j++) { if(!dp[j] && j >= money[i].val && dp[j - money[i].val] && used[j - money[i].val] < money[i].num) { ans = max(ans, j); dp[j] = true; used[j] = used[j - money[i].val] + 1; } } } printf("%d\n", ans); } return 0; }
原文:http://www.cnblogs.com/Apro/p/4822416.html