题目链接:点击打开链接
题解思路:这里我们将连续两个的1或0绑在一起将他的权值改成2然后就可以构成一个0、1交替的字符串然后又出现三种情况
1、
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
2、当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]);
3.中间一个球和左右边界抵消if(a[i]+a[j]<4)这里一定要小于4不如任意一边都会先和夹在里面的那个球抵消另一边就无法抵消
代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
char s[250];
int a[250];
int dp[250][250];
int main()
{
int t;
int kase=0;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
int n=strlen(s);
int m=1;
a[1]=1;
for(int i=1;i<n;i++)
{
if(s[i]==s[i-1])a[m]++;
else a[++m]=1;
}
for(int len=0;len<=m;len++)
{
for(int i=1;i<=m;i++)
{
int j=i+len;
if(j<=m&&j>=1)
{
dp[i][j]=2*n;
if(len==0)
{
dp[i][j]=3-a[i];
}
else
{
for(int k=i;k<j;k++)
{
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
}
if((j-i-1)%2==1)
{
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][m]);
}
}