1. 程式人生 > >洛谷P2679 子串 dp

洛谷P2679 子串 dp

正解:dp+滾動陣列(...是叫這個名兒趴qwq

解題報告:

感覺是道dp好題啊,所以就寫了個題解

程式碼實現難度低,思維難度大,像我這種思維僵化傻逼選手只想到了爆搜+組合數學...

其實是道很妙的dp題!好趴也沒有多妙主要大概是妙在想到了dp?具體實現很普通的

然後程式碼沒什麼要解釋的鴨,真的不難,主要覺得題目出得還是挺好的趴,像我這種傻逼根本想不到是dp的鴨...然後實在是想放上來就放上來了

具體實現隨便說點兒趴

就f[i][j][k]:A串掃到i B串掃到j 有k個空格 然後這裡會發現有倆問題

1)因為f存的是個和我並不知道有多少是上一位匹配上的也就不知道上一個相等的那個位置和這一位之間有沒有斷電

2)ijl乘起來太大了會MLE掉

解決方法對應也是倆

1)再開個輔助陣列g[i][j][k]表示是正兒八經這一位匹配上的

2)可以發現每次轉移時i只和上一個i有關,滾動陣列處理掉就好

over

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rp(i,x,y) for(register ll i=x;i<=y;++i)
#define my(i,x,y) for(register ll i=x;i>=y;--i)

const
ll mod=1000000007; ll n,m,cjk,f[2][210][210],g[2][210][210]; bool now=1; string a,b; inline ll read() { char ch=getchar();ll x=0;bool y=1; while(ch!='-' && (ch>'9' || ch<'0'))ch=getchar(); if(ch=='0')y=0,ch=getchar(); while(ch>='0' && ch<='9')x=(x<<1)+(x<<3
)+(ch^'0'),ch=getchar(); return y?x:-x; } int main() { string s; n=read();m=read();cjk=read();cin>>a>>b;f[0][0][0]=1;a=' '+a;b=' '+b; rp(i,1,n) { f[now][0][0]=1; rp(j,1,m) { rp(k,1,cjk) { if(a[i]==b[j])g[now][j][k]=(f[now^1][j-1][k-1]+g[now^1][j-1][k])%mod;//g:可以從之前的f轉移來,就必有空格本來沒空格也強行當有 也可以從上一位的g轉移來,就中間沒有空格 else g[now][j][k]=0; f[now][j][k]=(f[now^1][j][k]+g[now][j][k])%mod; } } now^=1; } printf("%lld\n",f[now^1][m][cjk]); return 0; }
反正我就是覺得這題很好qwq