ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K.

ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K. Poor Ramzi -dp+記憶化搜索


【Problem Description】

給你一串\(01\)字符串,將其劃分,使得劃分後,分別求出每組\(01\)之和後是迴文的,求劃分的方案數,ios

【Solution】

定義\(dp[l][r]\)表示,區間\([l,r]\)中知足條件的方案數是多少。\(dfs(i+1,j-1)\)表示在\(i,i+1\)之間插入一個隔板,在\(j-1,j\)之間插入一個隔板。枚舉全部可能隔板的插入位置來轉移便可。注意自身總體也算是一種方案。c++


【Code】

/*
 * @Author: _Simon_
 * @Date: 2019-11-07 11:31:32 
 * @Last Modified by: _Simon_
 * @Last Modified time: 2019-11-07 11:31:32
 */ 
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define maxn 205
#define INF 0x3f3f3f3f
const int mod=1e9+7;
string s;
int dp[maxn][maxn]; //dp[l][r]表示區間[l,r]的劃分方案數
int dfs(int l,int r){ 
    if(l>=r) return 1;
    if(dp[l][r]) return dp[l][r];
    dp[l][r]=1; //自身也是一種方案
    int left=0,right=0;
    for(int i=l;i<r;i++){ //枚舉隔板插入的位置
        left+=s[i]-'0';right=0;
        for(int j=r;j>i;j--){
            right+=s[j]-'0'; //記錄和
            if(left==right) (dp[l][r]+=dfs(i+1,j-1))%=mod; 若是知足條件,統計方案數
        }
    }
    return dp[l][r];
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int T;cin>>T;
    while(T--){
        memset(dp,0,sizeof(dp));
        cin>>s;int n=s.size();
        cout<<dfs(0,n-1)<<endl;
    }
    return 0;
}
相關文章
相關標籤/搜索