【题解】P5879 题解
P5879 题解
简单的 DP 题目。
DP 的话,首先你要弄明白怎么转移。
当时我是在某场模拟赛看到了这道题,我就去枚举了一下当 为 时的所有情况。
这里明确一下,第 行代表有 个格子的那一行。
我们是怎么枚举的呢?小学的时候老师告诉过我们,枚举要有序。放到这题来讲,我们先枚举第三行放三个,再枚举第三行放二个,最后再枚举第三行放一个和不放。如果第三行放三个,那么还要继续枚举第二行放二个、一个和不放。
一般化地来讲,当我们枚举第 行放 个时,我们就要枚举第 行放 到 的情况。当然,有时候由于第 行只有 个格子,所以事实上放不到 个。也就是说,实际上要枚举的是 行放 到 的情况。
于是递推式先出来了:
其中 。
此时还要注意,当我们枚举到最后一个的时候,也就是第 格的时候,只有两种情况:放一个和不放,这个时候不用枚举,直接就是一种情况,即 。
直接按式子推就可以了。
最后的答案是 。
代码如下:
int n;
cin >> n;
f[1][1] = f[1][0] = 1;
for(int i = 2;i <= n;i++)
{
for(int j = 0;j <= i;j++)
{
for(int k = 0;k <= min(j, i - 1);k++)
{
f[i][j] += f[i - 1][k];
}
}
}
int sum = 0;
for(int i = 0;i <= n;i++)
{
sum += f[n][i];
}
cout << sum - 1 << endl;
但是需要注意,这题高精度。
由于我不想写高精度,于是写了一个打表的 Python 程序,如下:
for n in range(1,101):
f=[]
for i in range(0,211):
q=[]
for j in range(0,211):
q.append(0)
f.append(q)
f[1][1] = f[1][0] = 1
for i in range(2, n + 1):
for j in range(i + 1):
for k in range(min(j, i-1)+1):
f[i][j] += f[i - 1][k]
sum = 0
for i in range(n + 1):
sum += f[n][i]
print('"'+str(sum - 1)+'",',end='')
这个本质上就是计算 到 的答案,由于 Python 自带高精度,所以该程序可以得到正确的答案。
然后把这个打出来的表写进去就可以了。
#include <iostream>
#include <string>
using namespace std;
const int N = 2e2 + 10;
string t[N] = /*表见https://www.luogu.com.cn/paste/4u4gehh1*/;
int main()
{
int n;
cin >> n;
cout << t[n] << endl;
return 0;
}

浙公网安备 33010602011771号