NOIP2015子串(洛谷2679)

2021-08-07 23:53:50 字數 2028 閱讀 7169

標籤:dp

題目描述

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

輸入輸出格式

輸入格式:

輸入檔名為 substring.in。

第一行是三個正整數 n,m,k,分別表示字串 a 的長度,字串 b 的長度,以及問

題描述中所提到的 k,每兩個整數之間用乙個空格隔開。 第二行包含乙個長度為 n 的字串,表示字串 a。第三行包含乙個長度為 m 的字串,表示字串 b。

輸出格式:

輸出檔名為 substring.out。 輸出共一行,包含乙個整數,表示所求方案數。由於答案可能很大,所以這裡要求[b]輸出答案對1,000,000,007 取模的結果。[/b]

輸入輸出樣例

輸入樣例#1:

6 3 1

aabaab

aab輸出樣例#1:2

輸入樣例#2:

6 3 2

aabaab

aab輸出樣例#2:7

輸入樣例#3:

6 3 3

aabaab

aab輸出樣例#3:7

說明

對於第 1 組資料:1≤n≤500,1≤m≤50,k=1;

對於第 2 組至第 3 組資料:1≤n≤500,1≤m≤50,k=2; 對於第 4 組至第 5 組資料:1≤n≤500,1≤m≤50,k=m; 對於第 1 組至第 7 組資料:1≤n≤500,1≤m≤50,1≤k≤m;對於第 1 組至第 9 組資料:1≤n≤1000,1≤m≤100,1≤k≤m; 對於所有 10 組資料:1≤n≤1000,1≤m≤200,1≤k≤m。

題意:

給出兩個字串,長度為 n 的 a 和長度為 m 的 b,現在要 在 a 串中取出 k 串互不重疊的⼦串,使得這 k 個⼦串連線 起來之後和 b 串相同,問有多少種⽅案。

分析:

方法一:(如下**)

這種資料範圍也就只有dp可行了

記憶陣列f[i][j][k][x]字串a的前i個字元和字串b的前j個字元用了k個子串

當x=0時表示字串a的第i個字元必須被選中

當x=1時表示字串a的第i個字元不能被選中

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

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];

ans=f[n][m][k][0]+f[n][m][k][1]

空間問題可能會爆,可以使用滾動陣列

方法二:dp計數

f[i][j][k]表示a[1..i]分成j段與b[1..k]相等的方案數

轉移同樣借助輔助陣列g[i][j][k]表示當前這段還未分完的

這種方法是聽武爺爺講的,然而並不會寫**【無奈】

參考**

#includeusing namespace std;

const int maxn=1005,maxm=205;

const long long mod=1e9+7;

int n,m,kk;

long long f[2][maxm][maxm][2];

char a[maxn],b[maxn];

int main()

}cout<<(f[n&1][m][kk][0]+f[n&1][m][kk][1])%mod<

NOIP2015子串題解

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

題解 NOIP 2015 子串

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

解題報告 NOIP2015 子串

這是一道dp題,然後來想想怎麼表示狀態,對答案有影響的就是a串的第i個字元,b串的第j個字元,和k個子串,簡單來說就是和選取的字元和子串的數量有關.那麼設 f i j kk 表示在a串的前i個字元中選kk個子串匹配b串的前j個字元的方案數.求方案數可以採用加法原理,考慮a串的第i個字元,那麼這個字元...