Find the minimal balls you have to insert to remove all the balls on the table.
Each test case contains a line with a non-empty string of 0 and 1 describing the row of balls at the start.
題意:
給你一串01串,你可以在任意位置插入0或1,有三個及以上的連續的相同的會消去,會有連鎖反應,問至少插入幾次能消完
思路:聽說是個原題,,,這場真多原題
有三種消除方式:
1.直接將區間分成兩部分,各消各的。
2.如果兩頭是同色的,可以消完中間的,合併後消去兩頭,代價和兩頭的數量有關。
3.如果兩頭同色,又存在一頭只有一個連續的情況,可以中間再找一個相同顏色的,三個合併後再消。
//
// main.cpp
// 1007
//
// Created by zc on 2017/9/18.
// Copyright © 2017年 1004. All rights reserved.
//
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=220;
char s[N];
int a[N],f[N][N];
int main(int argc, const char * argv[]) {
int T,kase=0;
scanf("%d",&T);
while(T--)
{
scanf("%s",s);
int n=strlen(s),m=0;
a[++m]=1;
for(int i=1;i<n;i++)
{
if(s[i]!=s[i-1]) a[++m]=0;
a[m]++;
}
for(int i=m;i>0;i--)
for(int j=i;j<=m;j++)
{
if(i==j)//i==j 直接返回需要補充的數量
{
f[i][j]=3-a[i];
continue;
}
f[i][j]=n+n;//初始化最大值爲2*n
for(int k=i;k<j;k++) f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);//分成兩半考慮
if((j-i)&1) continue;//如果間隔爲奇數,則不是同種顏色
f[i][j]=min(f[i][j],f[i+1][j-1]+(a[i]+a[j]==2));//i和j同色,可以等中間消掉,如果兩邊都是1還得加上1的代價
if(a[i]+a[j]<4)//如果i和j存在有1,可以i,k,j三個同色的一起消
{
for(int k=i+2;k<j;k+=2)
if(a[k]==1) f[i][j]=min(f[i][j],f[i+1][k-1]+f[k+1][j-1]);
}
}
printf("Case #%d: %d\n",++kase,f[1][m]);
}
}