Luogu P2679 子串(字串+dp)

來源:互聯網
上載者:User

標籤:string   不同   typedef   方案   優秀   沒有   包含   lin   alt   

P2679 子串

題意題目描述

有兩個僅包含小寫英文字母的字串\(A\)和\(B\)。

現在要從字串\(A\)中取出\(k\)個互不重疊的非空子串,然後把這\(k\)個子串按照其在字串\(A\)中出現的順序依次串連起來得到一個新的字串。請問有多少種方案可以使得這個新串與字串\(B\)相等?

注意:子串取出的位置不同也認為是不同的方案。

輸入輸出格式輸入格式:

第一行是三個正整數\(n,m,k\),分別表示字串\(A\)的長度,字串\(B\)的長度,以及問題描述中所提到的\(k\),每兩個整數之間用一個空格隔開。

第二行包含一個長度為\(n\)的字串,表示字串\(A\)。

第三行包含一個長度為\(m\)的字串,表示字串\(B\)。

輸出格式:

一個整數,表示所求方案數。

由於答案可能很大,所以這裡要求輸出答案對\(1000000007\)模數的結果。

輸入輸出範例輸入範例:
6 3 1aabaabaab
輸出範例:
2
輸入範例:
6 3 2aabaabaab
輸出範例:
7
輸入範例:
6 3 3aabaabaab
輸出範例:
7
說明

對於第\(1\)組資料:\(1 \leq n \leq 500,1 \leq m \leq 50,k=1\);

對於第\(2\)組至第\(3\)組資料:\(1 \leq n \leq 500,1 \leq m \leq 50,k=2\);

對於第\(4\)組至第\(5\)組資料:\(1 \leq n \leq 500,1 \leq m \leq 50,k=m\);

對於第\(1\)組至第\(7\)組資料:\(1 \leq n \leq 500,1 \leq m \leq 50,1 \leq k \leq m\);

對於第\(1\)組至第\(9\)組資料:\(1 \leq n \leq 1000,1 \leq m \leq 100,1 \leq k \leq m\);

對於所有\(10\)組資料:\(1 \leq n \leq 1000,1 \leq m \leq 200,1 \leq k \leq m\)。

思路

你可以看一篇優秀的部落格。 --alecli

這位神犇叫為了我這道題。

設計狀態\(dp[i][j][k][0/1]\),\(i\)表示\(A\)字串的前\(i\)位,\(j\)表示\(B\)字串的前\(j\)位,\(k\)表示選取了多少個子串,\(0/1\)表示當前字元有沒有選入子串中。

如果該位沒有選,那麼轉移是顯然易見的:

\[dp[i][j][k][0]=dp[i-1][j-1][k][1]+dp[i-1][j-1][k][0]\]

它表示不論前一位選與不選,我都加一個空格,分開上一子串和下一子串

而如果要選這一位,就要分類討論這一位上的\(A\)與\(B\)是否相同。

  • 如果不同,那麼\(dp[i][j][k][0]=0\);
  • 如果相同,那麼\(dp[i][j][k][0]=dp[i-1][j-1][k][1]+dp[i-1][j-1][k-1][1]+dp[i-1][j-1][k-1][0]\),它表示繼續下一子串、在上一子串聯續的情況下重新開始新一子串、直接作為新子串的開頭。

那麼答案就是\(dp[n][m][k][0]+dp[n][m][k][1]\)了。

順便,My Code怕空間不足,寫了滾動數組。如果不寫的話,要記得初始化\(dp\)數組的值。

AC代碼
#include<bits/stdc++.h>using namespace std;typedef long long LL;const LL P=1000000007;LL n,m,k,dp[2][202][202][2];string a,b;int main(){    cin>>n>>m>>k;    cin>>a>>b;    a=' '+a;    b=' '+b;    dp[0][0][0][0]=dp[1][0][0][0]=1;    for(LL i=1;i<=n;i++)        for(LL j=1;j<=m;j++)            for(LL p=1;p<=k;p++)            {                dp[i&1][j][p][0]=(dp[(i-1)&1][j][p][0]+dp[(i-1)&1][j][p][1])%P;                if(a[i]==b[j]) dp[i&1][j][p][1]=(dp[(i-1)&1][j-1][p][1]+dp[(i-1)&1][j-1][p-1][0]+dp[(i-1)&1][j-1][p-1][1])%P;                else dp[i&1][j][p][1]=0;            }    printf("%lld",(dp[n&1][m][k][1]+dp[n&1][m][k][0])%P);    return 0;}

Luogu P2679 子串(字串+dp)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.