CF1989E Distance to Different 题解

CF1989E Distance to Different

好题。题目要求 b 数组的数量,但 b 数组难以直接计算,而 b 数组和 a 数组的映射关系并不明显。考虑分析 b 的性质,并映射到其他数组。

我们发现,b 数组与 a 数组中元素的具体数值无关,只与 a 数组中元素的不等关系有关。因此,我们考虑把 b 数组映射到一个反映 a 数组中元素的不等关系的数组。

ci=[aiai1],特别的,不难发现 c1=0。考虑将 b 数组映射到 c 数组。题目中要求 k 个元素至少出现一次,所以至少有 k1ci 等于 1。若至少有 k1ci 等于 1,则一定可以构造出一个 a 数组满足条件,每次不同时换新的元素即可。因此,这个 c 数组是可行的,对应的 b 数组也是可行的。

但是,b 数组和 c 数组并不是严格的双射关系。c=[1,0,1]c=[1,1,1] 时,b 数组均为 [1,1,1]。因此,我们需要强制舍去其中一种情况以保证双射。由于至少有 kci 等于 1,显然应该舍去 [1,0,1],这样可以获得更多的 ci=1,否则可能无法满足条件。

最后,我们使用动态规划计算满足条件的 c 数组数量。设状态 f[i][j][k][l] 表示第 i 个位置,前 1 位为 j,这一位为 k,一共出现 lci=1 的情况,显然有如下转移方程:

f[i][j][0][l]=f[i][j][0][l]+f[i1][p][j][l]

f[i][j][1][l]=f[i][j][1][l]+f[i1][p][j][l1](p1j0)

初始 f[1][0][0][0]=1,目标 i=01j=01f[n][i][j][k1]

时间复杂度 O(nk),代码中采用了另一种转移方式。

#include <bits/stdc++.h>
using namespace std;
long long k,n,f[200001][2][2][11],ans=0;
const long long mod=998244353;
int main()
{
    scanf("%lld%lld",&n,&k);
    f[1][0][0][0]=1;
    for(int i=2;i<=n;i++)
        for(int j=0;j<=1;j++)
            for(int l=0;l<=1;l++)
                for(int p=0;p<=k-1;p++)
                    for(int q=0;q<=1;q++)
                        {
                        if(j==1&&l==0&&q==1)continue;
                        if(p+q>=k)f[i][l][q][k-1]+=f[i-1][j][l][p],f[i][l][q][k-1]%=mod;
                        else f[i][l][q][p+q]+=f[i-1][j][l][p],f[i][l][q][p+q]%=mod;
                        }
    for(int i=0;i<=1;i++)
        for(int j=0;j<=1;j++)
            ans+=f[n][i][j][k-1],ans%=mod;
    printf("%lld\n",ans);
	return 0;
} 
posted @   w9095  阅读(0)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示