python實現藉助360加固保程式碼實現批量、斷點再續等功能
題目描述
有兩個僅包含小寫英文字母的字串AA和BB。
現在要從字串AA中取出kk個互不重疊的非空子串,然後把這kk個子串按照其在字串AA中出現的順序依次連線起來得到一個新的字串。請問有多少種方案可以使得這個新串與字串BB相等?
注意:子串取出的位置不同也認為是不同的方案。
輸入格式
第一行是三個正整數n,m,kn,m,k,分別表示字串AA的長度,字串BB的長度,以及問題描述中所提到的kk,每兩個整數之間用一個空格隔開。
第二行包含一個長度為nn的字串,表示字串AA。
第三行包含一個長度為mm的字串,表示字串BB。
輸出格式
一個整數,表示所求方案數。
由於答案可能很大,所以這裡要求輸出答案對10000000071000000007取模的結果。
輸入輸出樣例
輸入 #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=11≤n≤500,1≤m≤50,k=1;
對於第 2 組至第 3 組資料:1≤n≤500,1≤m≤50,k=21≤n≤500,1≤m≤50,k=2;
對於第 4 組至第 5 組資料:1≤n≤500,1≤m≤50,k=m1≤n≤500,1≤m≤50,k=m;
對於第 1 組至第 7 組資料:1≤n≤500,1≤m≤50,1≤k≤m1≤n≤500,1≤m≤50,1≤k≤m;
對於所有 10 組資料:1≤n≤1000,1≤m≤200,1≤k≤m1≤n≤1000,1≤m≤200,1≤k≤m。
思路:
剛開始想到的狀態是
dp[i][j][k]:a字串的前i個匹配b字串的前j個用k個子串。
但是,這樣還不夠,因為第i個字元的使用情況會影響第i-1個字元的使用情況。
為什麼呢?見下面的情況分析。
所以我們還需要一維來表示使用與否。 使用過用1,沒用過用0,即 dp[i][j][k][0/1].
當a[i]==b[j],那麼第i個字元可以使用也可以不使用。
使用:dp[i][j][k][1]=dp[i-1][j-1][k][1]+dp[i-1][j-1][k-1][0]+dp[i-1][j-1][k-1][1];
dp[i-1][j-1][k][1]:使用第i個字元並且跟前面的第i-1個字元連線成為第k個子串,所以第i-1個字元必須使用。(即跟第i個字元有關)
dp[i-1][j-1][k-1][0]、dp[i-1][j-1][k-1][1] :當第i個字元單獨成新的子串,那麼第i-1個字元可用可不用(即跟第i個字元無關)
不使用:
dp[i][j][k][0]=dp[i-1][j][k][1]+dp[i-1][j][k][0] (即跟第i個字元無關)
當a[i]!=b[j]時,
不使用:
dp[i][j][k][0]=dp[i-1][j][k][1]+dp[i-1][j][k][0] (即跟第i個字元無關)
使用:dp[i][j][k][1]=0;
綜上所述,有
if(a[i]==b[j]){
dp[i][j][k][1]=dp[i-1][j-1][k][1]+dp[i-1][j-1][k-1][0]+dp[i-1][j-1][k-1][1];
}
else dp[i][j][k][1]=0;
dp[i][j][k][0]=dp[i-1][j][k][1]+dp[i-1][j][k][0] ;
關鍵程式碼就好啦~
邊界值 dp[0][0][0][0]=1 dp[1][0][0][0][0]=1
假如開四維陣列,根據資料範圍有1000*200*200*2,很有可能卡空間。
通過轉移方程發現,每次i行都是通過i-1行更新得到的,所以我們只要開兩行的空間,來回使用,即滾動陣列就好了。
#include<bits/stdc++.h>
using namespace std;
char a[1005],b[205];
int dp[2][205][205][2];
const int mod=1000000007;
int main(){
int n,m,k;
scanf("%d%d%d%s%s",&n,&m,&k,a+1,b+1);
dp[0][0][0][0]=1;
dp[1][0][0][0]=1;
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
for(int g=1; g<=k; g++){
if(a[i]==b[j]){
dp[i%2][j][g][1]=((dp[(i-1)%2][j-1][g-1][0]+dp[(i-1)%2][j-1][g-1][1])%mod+dp[(i-1)%2][j-1][g][1])%mod;
}
else{
dp[i%2][j][g][1]=0;
}
dp[i%2][j][g][0]=(dp[(i-1)%2][j][g][0]+dp[(i-1)%2][j][g][1])%mod;//不使用第i個
}
}
}
cout<<(dp[n%2][m][k][0]+dp[n%2][m][k][1])%mod<<endl;
return 0;
}