码迷,mamicode.com
首页 > 其他好文 > 详细

P2679 NOIP2015子串

时间:2017-08-13 16:18:38      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:space   ios   iostream   mod   return   状态   blog   swa   set   

技术分享

 

很自然想到DP

这道题使我意识到自己的DP功力还有很大不足

用f[i][j][k][0/1]表示A串到i位,B串到j位,A串分为了k部分,第i位是否匹配进B串的方案数(一般套路)

优化:滚动数组,设置pre,now,

教训:

  1、别图省事,把该写全的写全

  2、找个好弄一点的DP边界

  3、一个方程不大好转移就换一个,

  4、经常从i-1或j-1转移过来

  5、看数据范围猜循环

看到DP题时:

想状态,想转移,想边界,想决策();

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 1009
#define M 209
#define mod 1000000007
using namespace std;
int n,m,KK;
char s[N];
int a[N],b[M];

int f[2][M][M][2];
int cnt;

int pre,now;

int main(){
	cin>>n>>m>>KK;
	scanf("%s",s);
	for(int i=1;i<=n;++i)a[i]=s[i-1];
	scanf("%s",s);
	for(int i=1;i<=m;++i)b[i]=s[i-1];
	
	
	pre=0;now=1;
	for(int i=1;i<=n;++i){
		f[now][1][1][0]=cnt;
		if(a[i]==b[1]){
			f[now][1][1][1]=1;
			++cnt;
		}else{
			f[now][1][1][1]=0;
		}
		for(int j=2;j<=m;++j){
			for(int k=1;k<=KK;++k){
				f[now][j][k][0]=(f[pre][j][k][0]+f[pre][j][k][1])%mod;
				if(a[i]==b[j])f[now][j][k][1]=(f[pre][j-1][k-1][1]+f[pre][j-1][k-1][0]+(long long)f[pre][j-1][k][1])%mod;
				else f[now][j][k][1]=0;
			}
		}
		//memset(f[pre],0,sizeof(f[pre])); 
		swap(pre,now);
	}
	
	printf("%d\n",(f[pre][m][KK][0]+f[pre][m][KK][1])%mod);
	return 0;
}

  

P2679 NOIP2015子串

标签:space   ios   iostream   mod   return   状态   blog   swa   set   

原文地址:http://www.cnblogs.com/zzyer/p/7353571.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!