题目地址:http://poj.org/problem?id=1390
click_box(i,j,ex_len)
表示:
大块j的右边已经有一个长度为ex_len的大块(该大块可能是在合
并过程中形成的,不妨就称其为ex_len),且j的颜色和ex_len
相同,在此情况下将 i 到j以及ex_len都消除所能得到的最高分
。
于是整个问题就是求:click_box(0,n-1,0)
求click_box(i,j,ex_len)时,有两种处理方法,取最优者
假设j和ex_len合并后的大块称作 Q
1) 将Q直接消除,这种做法能得到的最高分就是:
click_box(i,j-1,0) + (len[j]+ex_len)
2
2) 期待Q以后能和左边的某个同色大块合并。需要枚举可能和Q
合并的大块。假设让大块k和Q合并,则此时能得到的最大
分数是:
click_box(i,k,len[j]+ex_len) + click_box(k+1,j-1,0)
click_box(i,j,ex_len) 递归的终止条件:i == j
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=200+5;
int color[maxn],blen[maxn];
int sorce[maxn][maxn][maxn];
int ClickBox(int i,int j,int len)
{int& ans=sorce[i][j][len];if(ans!=-1) return ans;ans=(blen[j]+len)*(blen[j]+len);if(i==j) return ans;ans+=ClickBox(i,j-1,0);for(int k=i;k<j;k++)if(color[k]==color[j])ans=max(ans,ClickBox(i,k,blen[j]+len)+ClickBox(k+1,j-1,0));return ans;
}
int main()
{int T;cin>>T;for(int t=1;t<=T;t++){int n,bNum=-1;cin>>n;memset(sorce,-1,sizeof(sorce));int last=0;for(int i=0;i<n;i++){int c;cin>>c;if(last!=c){bNum++;blen[bNum]=1;color[bNum]=c;last=c;}else blen[bNum]++;}printf("Case %d: %d\n",t,ClickBox(0,bNum,0));}return 0;
}