zoukankan      html  css  js  c++  java
  • NOIP2015 子串

    Description:

    给定 (A,B) 两个字符串,把 (A) 串分成 (k) 个连续不交叉子串,求把所有字串按顺序排起来得到 (B) 串的方案数。

    Solution:

    (f_{i,j,k,1/0}) 表示 (A_{1..i} , B_{1..j}) 且子串数为 (k) 的方案数。

    则:

    好像也可以设 (f_{i,j,k,0}) 表示选不选都行的方案数,同理方程就好推了qwq

    然后滚动优化一下就好了。

    (话说四维层面上的东西真是不好想

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 1e4;
    const int M = 1e3;
    const int mod = 1e9+7;
    int n,m,K;
    int f[M][M][2];
    char a[N],b[N];
    
    int main()
    {
    	scanf("%d%d%d
    ",&n,&m,&K);
    	gets(a+1);gets(b+1);
    	f[0][0][0]=1;
    	for(int i=1;i<=n;++i)
    	{
    		for(int j=min(i,m);j>=1;--j)
    		{
    			for(int k=1;k<=min(j,K);++k)
    			{
    				if(a[i]==b[j])
    				{
    					f[j][k][0]=(f[j][k][0]+f[j][k][1])%mod;
    					f[j][k][1]=((f[j-1][k-1][0]+f[j-1][k-1][1])%mod+f[j-1][k][1])%mod;//这里 % 一次导致调了1h-,真·细节决定成败。。。 
    				}
    				else if(a[i]!=b[j])
    				{
    					f[j][k][0]=(f[j][k][0]+f[j][k][1])%mod;
    					f[j][k][1]=0;
    				}
    			}
    		}
    	}
    	printf("%d
    ",(f[m][K][0]+f[m][K][1])%mod);
    	return 0;
    }
    

    Question:

    dp的初值问题:比如这道题,为啥 (f_{0,0,1} ot =1)

  • 相关阅读:
    c#将 1, 2, ..., 9共 9 个数字分成 3 组
    信息学院本科生创新项目总结
    Element-ui的使用
    fastmock接口管理
    mock安装与使用
    开闭原则
    里氏替换原则
    依赖倒置原则
    接口隔离原则
    单一职责原则
  • 原文地址:https://www.cnblogs.com/oierwyh/p/12261621.html
Copyright © 2011-2022 走看看