https://ac.nowcoder.com/acm/contest/554/A

看到神仙们的代码真的长知识了,以为是出题人忘了mod,结果居然是故意玩大数,写爆了啊。

然后发现了神仙们的大数原来是分块的,get

1、考虑某一行,如果这一行的下一行没有棋子,那么这是一种,所以将每一行没有棋子的情况初始化为1

2、假设当前第  行放了  个棋子并且第  行放棋子的方案数都知道 ,那么当前情况的方案数就等于第 行放 到个数字的方案数的总和。所以递推式为

3、然后发现要用大数?分块大法好。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod = 1e8;
const int N = 105;
ll dp[N][N][100];
ll ans[100];
int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 0; i <= n; i++)
			dp[i][0][1] = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= i; j++)
			for (int k = 0; k <= j; k++)
				for (int l = 1; l < 10; l++)
				{
					dp[i][j][l] = dp[i][j][l] + dp[i - 1][k][l];
					if (dp[i][j][l] > mod)
					{
						dp[i][j][l + 1] += dp[i][j][l] / mod;
						dp[i][j][l] %= mod;
					}
				}
	for (int i = 1; i <= n; i++)
		for (int l = 1; l < 10; l++)
		{
			ans[l] += dp[n][i][l];
			if (ans[l] > mod)
			{
				ans[l + 1] += ans[l] / mod;
				ans[l] %= mod;
			}
		}
	for (int l = 10; l >= 1; l--)
	{
		if (ans[l] != 0)
		{
			printf("%d", ans[l]);
			l--;
			while (l >= 1)
			{
				printf("%08lld", ans[l]);
				l--;
			}
		}
	}
}
/*
16 129644789
17 477638699
*/