Zuma
傳送門1
傳送門2
Think about the Zuma Game. You have a row of at most
Find the minimal balls you have to insert to remove all the balls on the table.
Input
The first line of input contains an integer
Each test case contains a line with a non-empty string of 0 and 1 describing the row of balls at the start.
Output
For each test case, output the case number and the minimal balls required to insert in a line.
Sample Input
4
10101
101001001
1001001001
01001101011001100
Sample Output
Case #1: 4
Case #2: 3
Case #3: 3
Case #4: 2
題意
一共有兩種顏色的祖瑪遊戲,每三個連在一起(或者大於三個)的球球就會被消除掉,問將這個字符串消除乾淨的最小吐球個數。
分析
定義
那麼顯然,玩過祖瑪的童鞋們都知道有三種消除一個區間方式(當然你沒玩過也肯定想的出來 ):實際上也可以認爲是兩種
1.將區間分成兩部分,各消除自身的部分:
2.將中間區間全部消除掉之後,兩端的相同顏色相撞刪除:
3.中間有1個球球,然後消除掉其左右兩側的部分之後,3部分相撞消除:
參考
CODE
#include<cstdio>
#include<cstring>
#define FOR(i,a,b) for(int i=(a),i##_END_=(b);i<=i##_END_;i++)
#define N 205
char s[N];
int cnt[N],dp[N][N];
inline void Min(int &x,int y) {if(x>y)x=y;}
int main() {
int t;
int cas=0;
scanf("%d",&t);
while(t--) {
scanf("%s",s);
int n=strlen(s),m=1;
cnt[1]=1;
FOR(i,1,n-1) {
if(s[i]==s[i-1])cnt[m]=2;
else cnt[++m]=1;
}
FOR(len,0,m)FOR(i,1,m) {
int j=i+len;
if(j<=m&&j>=1) {
if(len==0)dp[i][j]=3-cnt[i];
else {
dp[i][j]=n<<1;
FOR(k,i,j-1)Min(dp[i][j],dp[i][k]+dp[k+1][j]);//左邊消左邊的右邊消右邊的
if(!(len&1)) {
if(cnt[i]+cnt[j]==2)Min(dp[i][j],dp[i+1][j-1]+1);//左右相撞
else Min(dp[i][j],dp[i+1][j-1]);
if(cnt[i]+cnt[j]<=3)//左中右相撞
for(int k=i+2; k<j; k+=2)
if(cnt[k]==1)
Min(dp[i][j],dp[i+1][k-1]+dp[k+1][j-1]);
}
}
}
}
printf("Case #%d: %d\n",++cas,dp[1][m]);
}
return 0;
}