这是我的纸币问题 2 的代码
#include <iostream>
using namespace std;
const int S = 1e3 + 5, N = 1e4 + 5, I = 1 << 30, M = 1e9 + 7;
int n, w, a[S], f[N];
void read(int &a) {
int s = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') s = s * 10 + c - 48, c = getchar();
a = s * f;
}
int main() {
read(n), read(w);
for (int i = 1; i <= n; i++) read(a[i]);
f[0] = 1;
for (int i = 1; i <= w; i++)
for (int j = 1; j <= n; j++)
if (i - a[j] >= 0) f[i] = (f[i] + f[i - a[j]]) % M;
printf("%d", f[w]);
return 0;
}
这是纸币问题 3 的代码
#include <iostream>
using namespace std;
const int S = 1e3 + 5, N = 1e4 + 5, I = 1 << 30, M = 1e9 + 7;
int n, w, a[S], f[N];
void read(int &a) {
int s = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') s = s * 10 + c - 48, c = getchar();
a = s * f;
}
int main() {
read(n), read(w);
for (int i = 1; i <= n; i++) read(a[i]);
f[0] = 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= w; j++)
if (j - a[i] >= 0) f[j] = (f[j] + f[j - a[i]]) % M;
printf("%d", f[w]);
return 0;
}
这两个代码只有枚举 n 和 w 的先后的区别,我之所以这么写确实是我感觉两者有些区别,应该就是 lyd 蓝书里“阶段”和“转移”的区别(记错了勿喷 Orz),但我细想感觉状态的定义十分类似,都是 fi 为凑齐 i 元的方案数/组合数,我感觉有些区别但是又说不清楚问什么,求大佬教教为啥枚举 n 和 w 的顺序不一样 Orz