1、团队程序设计天梯赛-练习集-L3-001 凑零钱
参考:http://www.cnblogs.com/xingxing1024/p/5557825.html
解题思路:
硬币数越多且用的硬币数相同的情况下后面的硬币面值越大时字典序越小
定义 dp[j] 表示要支付的款额为 j 时需要的硬币的数量
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ull mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int maxn = 1e4 + 10;
int N, M;
int num[maxn];
int dp[110];
int pre[110];
int main()
{
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
#endif // __AiR_H
scanf("%d%d", &N, &M);
for (int i = 1; i <= N; ++i) {
scanf("%d", &num[i]);
}
sort(num+1, num+N+1);
memset(pre, 0, sizeof(pre));
for (int i = 1; i <= M; ++i) {
dp[i] = -INF;
}
dp[0] = 0;
for (int i = 1; i <= N; ++i) {
for (int j = M; j-num[i] >= 0; --j) {
if (dp[j] <= dp[j-num[i]] + 1) {
dp[j] = dp[j-num[i]] + 1;
pre[j] = j - num[i];
}
}
}
if (dp[M] > 0) {
int t = M;
stack<int> Stack;
while (t != 0) {
Stack.push(t - pre[t]);
t = pre[t];
}
printf("%d", Stack.top());
Stack.pop();
while (!Stack.empty()) {
printf(" %d", Stack.top());
Stack.pop();
}
printf("\n");
} else {
printf("No Solution\n");
}
return 0;
}