标签: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;
}
标签:space ios iostream mod return 状态 blog swa set
原文地址:http://www.cnblogs.com/zzyer/p/7353571.html