洛谷 2679 NOIP 2015 子串

2022-04-29 20:00:16 字數 1213 閱讀 2195

題目戳這裡

一句話題意

給你兩個字串a,b從a中取出k個不重合子串(順序與在a中順序相同)組成b,問有多少種方案?

solution

話說重打還是出各種錯誤也是醉了

先看題目,因為答案與a串,b串和拆分次數都有關,那麼我們把這些都定義進dp方程中:

定義f[i][j][k][0]代表選到a串的前i個字元中選k個子串組成b[1-j],且第i個不選。

那麼f[i][j][k][1]就是代表選到a串的前i個字元中選k個子串組成b[1-j],且第i個選。

定義好狀態就很好做了:

如果這個不選,那麼很明顯就等於前乙個 選+不選 ,所以:

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

那麼如果選呢?首先需要注意因為要選,所以需要a[i]==b[j],否則不匹配。先看轉移方程:

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

f[i-1][j-1][k][1]說明選i並且接在i-1後面組成一整個子串。

f[i-1][j-1][k-1][0] 因為i-1不選,所以需要從k-1轉移過來。

f[i-1][j-1][k-1][1] i-1選了,i也可以單獨組成子串。

注意事項:

1.因為模數是1e9+7,三個1e9+7就會爆int,所以第二個轉移方程需要加兩個模一下,再加第三個 (wa了40分)。

2.如果直接定義f陣列 空間複雜度是 1000200200*2=8e7 超過了128mb,並且我們的轉移方程中 i 的狀態只與 i-1 有關,所以需要滾掉第一維。

coding

#includeusing namespace std;

const int p = 1e9+7;

const int n = 205;

int t,n,m,f[2][n*5][n][2],k;

char a[n*5],b[n];

int main()

else f[t][j][k][1]=0;}}

cout<<(f[t][m][k][1]+f[t][m][k][0])%p;

return 0;

}

NOIP2015子串(洛谷2679)

標籤 dp 題目描述 有兩個僅包含小寫英文本母的字串 a 和 b。現在要從字串 a 中取出 k 個互不重疊的非空子串,然後把這 k 個子串按照其在字串 a中出現的順序依次連線起來得到一 個新的字串,請問有多少種方案可以使得這個新串與字串 b 相等?注意 子串取出的位置不同也認為是不同的方案。輸入輸出...

洛谷P2679 NOIP2015 子串

無 有兩個僅包含小寫英文本母的字串 a 和 b。現在要從字串 a 中取出 k 個互不重疊的非空子串,然後把這 k 個子串按照其在字串 a 中出現的順序依次連線起來得到一 個新的字串,請問有多少種方案可以使得這個新串與字串 b 相等?注意 子串取出 的位置不同也認為是不同的方案。輸入格式 輸入檔名為 ...

洛谷 P2679子串

題目背景 無 題目描述 有兩個僅包含小寫英文本母的字串 a 和 b。現在要從字串 a 中取出 k 個互不重疊的非空子串,然後把這 k 個子串按照其在字串 a 中出現的順序依次連線起來得到一 個新的字串,請問有多少種方案可以使得這個新串與字串 b 相等?注意 子串取出 的位置不同也認為是不同的方案。輸...