01两色的祖玛最优解,思路参考这里
消除区间[i,j]的球有三种方法:
1:消除[i,k]和[k+1][j]
2:消除[i+1,j-1]后两侧碰撞
3:三个离散的1块接触相消,要注意如果不是3个1的话先左或右会出现2的碰撞
#include<bits/stdc++.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<iostream>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<iomanip>
using namespace std;
#define ll long long
#define ld long double
#define pb push_back
#define FOR(a) for(int i=1;i<=a;i++)
const int inf=0x3f3f3f3f;
const int maxn=3e2+9;
char s[maxn];
int a[maxn];
int dp[maxn][maxn];
int main(){
int T,kase=0;
scanf("%d",&T);
while(T--){
scanf("%s",s);
int n=strlen(s);
int cnt=1;
a[1]=1;
for(int i=1;i<n;i++){
if(s[i]==s[i-1])a[cnt]++;
else a[++cnt]=1;
}
for(int len=0;len<=cnt;len++){
for(int i=1;i<=cnt;i++){ //从第几个块开始
int j=i+len;
if(j<1||j>cnt)continue;
dp[i][j]=2*n;
if(len==0){
dp[i][j]=max(1,3-a[i]);
}else{
for(int k=i;k<j;k++){ //第k个球后为分隔
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
}
if((j-i-1)%2==1){ //i,j块同色
if(a[i]+a[j]==2)
dp[i][j]=min(dp[i][j],dp[i+1][j-1]+1);
else //碰撞消除
dp[i][j]=min(dp[i][j],dp[i+1][j-1]);
if(a[i]+a[j]<4)
for(int k=i+2;k<j;k+=2){
if(a[k]==1)
dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k+1][j-1]);
}
}
}
}
}
printf("Case #%d: ",++kase);
printf("%d\n",dp[1][cnt]);
}
}