题目链接:https://www.acwing.com/problem/content/1025/
DP思路:
/*
f[i, j]:从1 - i中取选择,然后一共只有j元钱,属性是count;钱可以不用完
1.不选第i本书籍:f[i - 1, j]
2.选择第i本书籍:f[i - 1, j - v], f[i - 1, j - 2 * v] -> f[]
*/
初始版代码:
#include <iostream>
#include <cstdio>
using namespace std;
int a[10];
int f[10][1005];
int main(void) {
int n; scanf("%d", &n);
a[1] = 10, a[2] = 20, a[3] = 50, a[4] = 100;
for(int i = 0; i <= 5; i ++) f[i][0] = 1;
for(int i = 1; i <= 4; i ++)
for(int j = 1; j <= n; j ++) {
for(int k = 0; ; k ++) {
if(k * a[i] > j) break;
f[i][j] += f[i - 1][j - k * a[i]];
}
}
printf("%d\n", f[4][n]);
return 0;
}
加入滚动数组:
变化思路:
#include <iostream>
#include <cstdio>
using namespace std;
int a[10];
int f[1005];
int main(void) {
int n; scanf("%d", &n);
a[1] = 10, a[2] = 20, a[3] = 50, a[4] = 100;
f[0] = 1;
for(int i = 1; i <= 4; i ++)
for(int j = a[i]; j <= n; j ++)
f[j] += f[j - a[i]];
printf("%d\n", f[n]);
return 0;
}