題目戳這裡
一句話題意
給你兩個字串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 相等?注意 子串取出 的位置不同也認為是不同的方案。輸...