CF1811G2 Vlad and the Nice Paths (hard version) 题解

有一种比较暴力,不需要组合数的 DP。

先考虑在 G1 的限制(即 n100n\leq 100)下怎么做。

有一个比较显然的 DP,fi,j,kf_{i,j,k} 表示前 ii 个,长度为 jj,最后一个的颜色为 kk。转移时可以朴素地 O(1)O(1) 转移,注意 j1( modm)j \equiv 1(\bmod m) 时可以从 fi1f_{i-1} 的任意一个 kk 转过来,于是需要在 DP 的同时维护一下和以防复杂度退化。

回到 G2,考虑上文的状态就已经是三次方,首先要优化这个东西。这一步是容易的,因为 fif_i 仅有 fi1f_{i-1} 而来,滚动数组即可。

接着是转移过程。注意到上文中既有 k=aik=a_i 时才真正进行了 DP 值的修改,于是不枚举 kk,只枚举 jj 即可。

然而这么写有个问题是,如果最终某个 fi,j,kf_{i,j,k} 的方案数是 109+710^9+7 的倍数,取模变成 00,我们会认为不存在这种长度,于是会在第 2929 个点 WA。于是在 DP 时顺便记录一个 bool 数组表示这种情况是否有可能,转移和 DP 转移类似。

顺带一提:没注意到这个问题仍然能过 G1,可能是数据比较弱。

#include <bits/stdc++.h>
using namespace std;

const int N = 5005;
const long long MOD = 1e9 + 7;

int t, n, m, a[N];
long long f[N][N];
long long sum[N];
bool cb[N][N];
bool cc[N];

int main()
{
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> t;
	while (t--)
	{
		cin >> n >> m;
		for (int i = 1; i <= n; i++) cin >> a[i];
		for (int i = 0; i <= n; i++)
		{
			for (int j = 0; j <= n; j++) 
			{
				f[i][j] = 0ll, cb[i][j] = 0, sum[i] = 0ll, cc[i] = 0;
			}
		}
		f[0][0] = 1ll;
		sum[0] = 1ll;
		cb[0][0] = 1;
		cc[0] = 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = n; j >= 1; j--)
			{
				sum[j] = (sum[j] - f[j][a[i]] + MOD) % MOD;
				f[j][a[i]] = (f[j][a[i]] + f[j - 1][a[i]]) % MOD;
				cb[j][a[i]] |= cb[j - 1][a[i]];
				if (j % m == 1)
				{
					f[j][a[i]] = (f[j][a[i]] + sum[j - 1]) % MOD;
					cb[j][a[i]] |= cc[j - 1];
					f[j][a[i]] = (f[j][a[i]] - f[j - 1][a[i]] + MOD) % MOD;
				}
				sum[j] = (sum[j] + f[j][a[i]]) % MOD;
				cc[j] |= cb[j][a[i]];
			}
		}
		long long ans = 0ll;
		for (int j = 0; j <= n; j += m) 
		{
			long long sum = 0ll;
			bool flg = 0;
			for (int k = 0; k <= n; k++) 
			{
				sum = (sum + f[j][k]) % MOD;
				flg |= cb[j][k];
				//cout << "!!!: " << j <<" " << k << " " << f[n][j][k] << "\n"; 
			}
			if (flg)
			{
				ans = sum;
			}
		}
		cout << ans << "\n";
	}
	return 0;
}
posted @   HappyBobb  阅读(6)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示