NOIP2015 子串

f[i][j][k][0]表示a做到前i位,b做到前j位,有了k个子串且第i位不用的方案数

f[i][j][k][1]表示a做到前i位,b做到前j位,有了k个子串且第i位用的方案数

a[i]==b[j]:

f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]

f[i][j][k][1]=f[i-1][j-1][k][1]+f[i-1][j-1][k-1][1]+f[i-1][j-1][k-1][0]

a[i]!=a[j]

f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]

f[i][j][k][1]=0

滚动数组优化即可通过本题

#include<cstdio>
using namespace std;
const long long mod=1000000007;
long long f[2][205][205][2];
int n,m,k;
char a[1005],b[1005];
int main(){
	f[0][0][0][0]=f[1][0][0][0]=1ll;
	scanf ("%d%d%d",&n,&m,&k);
	scanf ("%s",a+1);scanf ("%s",b+1);
	for (register int i=1;i<=n;++i){
		for (register int j=1;j<=m;++j){
			for (register int w=1;w<=k;++w){
				if (a[i]==b[j]){
					f[i%2][j][w][0]=f[(i-1)%2][j][w][0]+f[(i-1)%2][j][w][1];
                    f[i%2][j][w][1]=f[(i-1)%2][j-1][w][1]+f[(i-1)%2][j-1][w-1][1]+f[(i-1)%2][j-1][w-1][0];
				}
				else{
					f[i%2][j][w][0]=f[(i-1)%2][j][w][0]+f[(i-1)%2][j][w][1];
                    f[i%2][j][w][1]=0;
				}
				f[i%2][j][w][0]%=mod;
				f[i%2][j][w][1]%=mod;
			}
		}
	}
	printf ("%lld\n",(f[n%2][m][k][0]+f[n%2][m][k][1])%mod);
	return 0;
}

  

上一篇:js-数据结构-链表


下一篇:4269. 【NOIP2015模拟10.27】挑竹签