http://janfan.cn/chinese/2015/01/21/dynamic-programming.html
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
const int N = 30000 + 5, NCOINS = 5;
long long arr[N];
int coins[] = { 1, 5, 10, 25, 50 };
#if 0
long long count_ways(int n) {
int i1, i5, i10, i25, i50;
long long cnt = 0;
for (i1 = 0; i1 <= n; i1++) {
for (i5 = 0; i5 * 5 <= n; i5++) {
for (i10 = 0; i10 * 10 <= n; i10++) {
for (i25 = 0; i25 * 25 <= n; i25++) {
for (i50 = 0; i50 * 50 <= n; i50++) {
int tmp = i1 + i5 * 5 + i10 * 10 + i25 * 25 + i50 * 50;
if (tmp == n) cnt++;
}
}
}
}
}
return cnt;
}
#endif
#if 1
long long count_ways_dp(int n) {
memset(arr, 0, sizeof(arr));
arr[0] = 1;
for (int i = 0; i < NCOINS; i++) {
for (int j = coins[i]; j <= n; j++) {
arr[j] += arr[j - coins[i]];
}
}
return arr[n];
}
#endif
int main()
{
int n;
while (~scanf("%d", &n)) {
long long ans = count_ways_dp(n);
if (ans > 1) {
printf("There are %lld ways to produce %d cents change.\n", ans, n);
}
else {
printf("There is only %lld way to produce %d cents change.\n", ans, n);
}
}
return 0;
}