NOIP2015子串題解

2021-08-08 18:43:12 字數 1570 閱讀 8214

題目描述

有兩個僅包含小寫英文本母的字串a和b。

現在要從字串a中取出k個 互不重疊 的非空子串,

然後把這k個子串按照其在字串a中出現的順序 依次連線 起來得到乙個新的字串,

請問有多少種方案可以使得這個新串與字串b相等?注意:子串取出的位置不同也認為是不同的方案。

輸入第一行是三個正整數n,m,k,分別表示字串a的長度,字串b的長度,以及問題描述中所提到的k,

每兩個整數之間用乙個空格隔開。

第二行包含乙個長度為n的字串,表示字串a。

第三行包含乙個長度為m的字串,表示字串b。

輸出輸出共一行,包含乙個整數,表示所求方案數。

由於答案可能很大,所以這裡要求輸出答案對1,000,000,007取模的結果。

樣例輸入

6 3 1

aabaab aab

樣例輸出

題解:dp。這題的**很短,但是個人感覺很難想狀態和狀態轉移方程。我也是在洛谷上看了題解才寫出來的。

s[i][j][k]表示a字串已經選到了第i個,b字串已經選到了第j個,在這個過程中一共選擇了k個字串,並且a[i]這個字元必須要選。

f[i][j][k]表示a字串已經選到了第i個,b字串已經選到了第j個,在這個過程中一共選擇了k個字串,並且a[i]這個字元不一定要選。

然後就可以推出狀態轉移方程式。

先是s[i][j][k],當a[i]==b[j]時,s[i][j][k]可以由兩種情況相加。乙個是將a[i]和b[j]單獨當作乙個新的字串的情況也就是s[i][j][k]+=f[i-1][j-1][k-1],還有一種就是a[i]是a[i-1]所在的子串的延續,所以s[i][j][k]+=s[i-1][j-1][k]。

所以s[i][j][k] = (f[i-1][j - 1][k - 1] + s[i-1][j - 1][k]) % mod;

然後是f[i][j][k],這種情況下不要求選擇a[i],所以f[i][j][k]也可以由兩種情況相加。也就是f[i][j][k] = (f[i-1][j][k] + s[i][j][k]) % mod;

下面貼**吧

#include

#include

#include

#include

using namespace std;

int f[2][2000][2000],n,m,k,s[2][2000][2000],mod= 1000000007;

char a[1000], b[1000];

void init()

void work()

else

f[now][j][k] = (f[fron][j][k] + s[now][j][k]) % mod;

// printf("%d %d %d %d %d\n", i, j, k, s[now][j][k], f[now][j][k]);}}

swap(now, fron);

}printf("%d", f[fron][m][k]);

}int main()

題解 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個字元,那麼這個字元...

NOIP2015提高組 子串

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