题目链接:点击打开链接
题解思路:这里我们将连续两个的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]); } }