只写了和dp有关的。。博客 https://www.cnblogs.com/huyufeifei/p/10351068.html
关于状态的继承和转移
这题的状态转移要分开两步来做:
1.继承之前状态的合法构造数量
2.构造出该状态下特有的新构造数量
这类dp尽量由已知状态推出未知态(加法转移)来做。。。自己用减法转移都不知道边界怎么写。。
#include <cstdio> #include <algorithm> const int N = 510, MO = 998244353; int f[N][N][2], sum[N]; inline void add(int &a, const int &b) { a = (a + b) % MO; return; } int main() { int n, k; scanf("%d%d", &n, &k); for(int j = 1; j <= n; j++) { f[0][j][0] = 1; } for(int i = 0; i <= n; i++) { for(int j = 1; j <= n; j++) { // f[i][j][0/1]继承前状态 for(int k = 1; k < j && i + k <= n; k++) { add(f[i + k][j][0], f[i][j][0]); add(f[i + k][j][1], f[i][j][1]); } if(i + j <= n) {//构造出新的方案 add(f[i + j][j][1], f[i][j][0]); add(f[i + j][j][1], f[i][j][1]); } } } for(int i = 1; i <= n; i++)printf("%d ", f[n][i][1]); long long ans = 0LL; for(int i = 1; i <= n; i++) for(int j = 1; (long long)j * i < k && j <= n; j++) ans = (ans + f[n][i][1] * f[n][j][1] % MO) % MO; ans = ans * 2 % MO; printf("%lld\n", ans); }