2
.子串
(substring.cpp/c/pas)
【問題描述】
有兩個僅包含小寫英文字母的字符串
A
和
B
。
現在要從字符串
A
中取出
k
個
互不重
疊
的非空子串,
然後把這
k
個子串按照其在字符串
A
中出現的順序依次連接起來得到一
個新的字符串,
請問有多少種方案可以使得這個新串與字符串
B
相等?注意:
子串取出
的位置不同也認爲是不同的方案
。
【輸入格式】
輸入文件名爲
substring.in
。
第一行是三個正整數
n
,
m
,
k
,分別表示字符串
A
的長度,字符串
B
的長度,以及問
題描述中所提到的
k
,每兩個整數之間用一個空格隔開。
第二行包含一個長度爲
n
的字符串,表示字符串
A
。
第三行包含一個長度爲
m
的字符串,表示字符串
B
。
【輸出格式】
輸出文件名爲
substring.out
。
輸出共一行,包含一個整數,表示所求方案數。
由於答案可能很大,所以這裏要求輸
出答案對
1,000,000,007
取模的結果。
【輸入輸出樣例
1
】
substring.in
substring.out
6 3 1
aabaab
aab
2
見選手目錄下
substring/substring1.in
與
substring/substring1.ans
。
【輸入輸出樣例
2
】
substring.in
substring.out
6 3 2
aabaab
aab
7
見選手目錄下
substring/substring2.in
與
substring/substring2.ans
。
【輸入輸出樣例
3
】
substring.in
substring.out
6 3 3
aabaab
aab
7
見選手目錄下
substring/substring3.in
與
substring/substring3.ans
。
【輸入輸出樣例說明】
所有合法方案如下:
(加下劃線的部分表示取出的子串)
樣例
1
:
aab
aab / aab
aab
樣例
2
:
a ab
aab /
a
aba
ab
/ a
a
ba
ab
/ aab
a ab
aa b
aab /
aa
baa
b
/ aab
aa b
樣例
3
:
a a b
aab /
a a
baa
b
/
a
ab
a
a
b
/
a
aba
a
b
a
a
b
a
a
b
/ a
a
ba
a
b
/ aab
a
a
b
【輸入輸出樣例
4
】
見選手目錄下
substring/substring4.in
與
substring/substring4.ans
。
【數據規模與約定】
對於第
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
。
題解:這道dp題和樹形dp的有一個思想很像,考慮當前這一位能否延續到後面用0/1表示,也就是說dp【i】【j】【k】【0/1】表示A串前i位B串前j位用了k部分,不能/能往後延續。用滾動數組優化空間。#include<cstdio>
#include<cstring>
const int mod=1000000007;
int dp[2][210][210][2];
char a[1010],b[210];
int main()
{
int i,j,k,m,n,l,p,q,x,y,z;
scanf("%d%d%d",&n,&m,&l);
scanf("%s",a+1);
scanf("%s",b+1);
dp[0][0][0][0]=dp[1][0][0][0]=1;
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
for (k=1;k<=l;k++)
{
dp[i&1][j][k][0]=dp[i&1^1][j][k][0];
if (a[i]==b[j])
{
dp[i&1][j][k][1]=(dp[i&1^1][j-1][k][1]+dp[i&1^1][j-1][k-1][0])%mod;
dp[i&1][j][k][0]=(dp[i&1][j][k][0]+dp[i&1][j][k][1])%mod;
}
}
for (j=1;j<=m;j++)
for (k=1;k<=l;k++)
dp[i&1^1][j][k][0]=dp[i&1^1][j][k][1]=0;
}
printf("%d\n",dp[n&1][m][l][0]);
}