Hdu 6212 Zuma 区间DP
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]); } }