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]);
	}
}


posted @ 2017-09-21 19:28  Drenight  阅读(100)  评论(0编辑  收藏  举报