考点
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int LEN = 1e3 + 10;
ll mem[LEN];
ll dfs(int x) { if (mem[x]) return mem[x]; if (x == 0 || x == 1) return mem[x] = 1; for (int i = 0; i <= x / 2; ++i) mem[x] += dfs(i); return mem[x]; }
int main() { int n; cin >> n; cout << dfs(n); }
|
思路
设mem[n]为数字n的合法数列个数;令mem[0] = 1,意为数字n本身构成的序列,数列末尾什么也不加
显然能得到状态转移方程: \[
mem\left[ 0 \right] +mem\left[ 1 \right] +...mem\left[ n/2 \right]
\rightarrow mem\left[ n \right]
\] 题解是递归编写的,将其改为递推也是可以的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int LEN = 1e3 + 10;
ll dp[LEN];
int main() { int n; cin >> n; dp[0] = dp[1] = 1; for (int i = 2; i <= n; ++i) { for (int j = 0; j <= i / 2; ++j) { dp[i] += dp[j]; } } cout << dp[n]; }
|