• CF666C Codeword 组合数


    题意:

    戳这里

    分析:

    • 暴力

    (O(n^2)) 的 DP ,(f[i][j]=f[i-1][j-1]+f[i][j-1]*25)

    • 正解

    我们发现 DP 方程与原串的形态无关,然后观察(题解) 式子,发现它可以通过组合数优化

    (f_{i,j}=C_{i-1}^{j-1} imes 25^{j-i}+C_i^{j-1} imes 26)

    这个递推式的含义就是:

    1. (j-1) 位匹配上了原来 (i-1) 个,为了避免算重,每一位的取值不能等于下一个要匹配的数,所以取值种类有 25 种,空余位置有 (j-i)

    2. (j-1) 位匹配完了,之后随意取

    然后我们对于长度对应的答案进行记忆化,由于不同长度的串的种类数最多只有 (sqrt{10^5}) 种,所以复杂度是 (O(nsqrt{n}))

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    namespace zzc
    {
    	inline int read()
    	{
    		int x=0,f=1;char ch=getchar();
    		while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    		while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    		return x*f;
    	}
    	
    	const int maxn = 1e5+5;
    	const int mod = 1e9+7;
    	char ch[maxn];
    	vector<int> f[maxn];
    	int fac[maxn],inv[maxn],pw[maxn];
    	bool vis[maxn];
    	int n,len;
    	
    	void init()
    	{
    		fac[0]=fac[1]=inv[0]=inv[1]=pw[0]=1;
    		pw[1]=25;
    		for(int i=2;i<=100000;i++) fac[i]=1ll*fac[i-1]*i%mod,inv[i]=1ll*inv[mod%i]*(mod-mod/i)%mod,pw[i]=1ll*pw[i-1]*25%mod;
    		for(int i=2;i<=100000;i++) inv[i]=1ll*inv[i-1]*inv[i]%mod;
    	}
    	
    	long long C(long long n,long long m)
    	{
    		return 1ll*fac[n]*inv[n-m]%mod*inv[m]%mod;
    	}
    	
    	void solve()
    	{
    		if(!vis[len])
    		{
    			vis[len]=true;
    			for(int i=0;i<len;i++) f[len].push_back(0);
    			for(int i=len;i<=100000;i++) f[len].push_back((1ll*C(i-1,len-1)*pw[i-len]%mod+1ll*f[len][i-1]*26%mod)%mod);
    		}
    		printf("%d
    ",f[len][read()]%mod);
    	}
    	
    	void work()
    	{
    		init();
    		n=read();
    		scanf("%s",ch);len=strlen(ch);
    		for(int i=1;i<=n;i++) 
    		{
    			if(read()==1) 
    			{
    				scanf("%s",ch);
    				len=strlen(ch);
    			}
    			else solve();
    		}
    	}
    
    }
    
    int main()
    {
    	zzc::work();
    	return 0;
    }
    
    
  • 相关阅读:
    DAY 42 前端
    DAY 41 mysql
    DAY 40 前端学习
    DAY 39 前端学习
    DAY 38 前端学习
    DAY 37 前端学习
    上传一个桌面
    找到anaconda中自带的qtdesigner,设计ui文件并生成py文件
    python课程:python3的数字与字符串
    python3 偏最小二乘法实现
  • 原文地址:https://www.cnblogs.com/youth518/p/14084749.html
Copyright © 2020-2023  润新知