NOIP模拟 地图map

NOIP模拟 地图map_第1张图片

  • 这道题我们很明显的发现肯定是动态规划
  • 当然以博主的智商,肯定是巧妙的推错了(留下苦涩的泪水)
  • 正解的状态还听我慢慢道来
  • 我们设f[i][j]为i个度数为2的点,其中j个点在环上(即剩下的i-j个点在链上)的方案数
  • 得到了以下三种转移方程NOIP模拟 地图map_第2张图片
  • 然后发现链的个数是由度数为1的点的个数决定的
  • 最后给出代码
#include
using namespace std;
typedef long long ll;
const ll N = 2005;
const ll mod = 998244353;
ll n,now,a1,a2,f[N][N],ans;
void In(ll &x)
{
	ll f = 1;
	x = 0;
	char c = getchar();
	while (c < '0' || c > '9')
	{
		if (c == '-') f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
	{
		x = x * 10 + c - '0';
		c = getchar();
	}
	x = x * f;
	return;
}
void Out(ll x)
{
	if (x < 0)
	{
		putchar('-');
		x = -x;
	}
	if (x > 9)
	{
		Out(x / 10);
	}
	putchar(x % 10 + '0');
}
int main()
{
	In(n);
	for (ll i = 1; i <= n; i++)
	{
		In(now);
		now&1?a1++:a2++;
	}
	if (a1&1)
	{
		putchar('0');
		return 0;
	}
	f[0][0] = 1;
	for (ll i = 1; i <= a2; i++)
	{
		for (ll j = 0; j <= i; j++)
		{
			if (j >= 3)
			{
				f[i][j] = f[i-3][j-3] * ((i - 1) * (i - 2) >> 1) % mod;
			}
			if (j >= 1)
			{
				f[i][j] = (f[i][j] + f[i-1][j-1] * (j-1)) % mod;
			}
			f[i][j] = (f[i][j] + f[i-1][j] * (a1 / 2 + i - j - 1)) % mod;
		}
	}
	for (ll i = 0; i <= a2; i++)
		ans = (ans + f[a2][i]) % mod;
	for (ll i = 3; i <= a1; i++)
		if (i & 1) ans = (ans *= i) % mod;
	Out(ans);
	return 0;
}

你可能感兴趣的:(NOIP模拟 地图map)