1. 程式人生 > >2018.11.04 洛谷P2679 子串(線性dp)

2018.11.04 洛谷P2679 子串(線性dp)

傳送門 為什麼前幾年的noipnoip總是出這種送分題啊? 這個直接線性dpdp不就完了嗎? f[i][j][k][0/1]f[i][j][k][0/1]表示當前在第ii個位置,已經匹配到了第jj個位置,已經使用了kk段,當前這個字元沒用用/用了。 然後分情況簡單轉移一下就行了。 注意可以滾動陣列優化空間。 程式碼:

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7,N=1005,M=205;
int n,m,K,ans=0,f[2][M][M][2],tmp=0;
char s[
N],t[M]; int main(){ scanf("%d%d%d%s%s",&n,&m,&K,s+1,t+1); f[tmp][0][0][0]=1; for(int i=1;i<=n;++i){ tmp^=1,memset(f[tmp],0,sizeof(f[tmp])),f[tmp][0][0][0]=1; for(int j=1;j<=m;++j){ for(int k=1;k<=K;++k){ f[tmp][j][k][0]=f[tmp^1][j][k][1]+f[tmp^1][j][k][0]; if(f[tmp][j]
[k][0]>=mod)f[tmp][j][k][0]-=mod; if(s[i]==t[j]){ f[tmp][j][k][1]=f[tmp^1][j-1][k][1]+f[tmp^1][j-1][k-1][0]; if(f[tmp][j][k][1]>=mod)f[tmp][j][k][1]-=mod; f[tmp][j][k][1]+=f[tmp^1][j-1][k-1][1]; if(f[tmp][j][k][1]>=mod)f[tmp][j][k][1]-=mod; } } } } ans=f[tmp]
[m][K][1]+f[tmp][m][K][0]; if(ans>=mod)ans-=mod; cout<<ans; return 0; }