您的位置:首页 > 其它

POJ 1390 Blocks (DP)

2017-01-22 10:20 260 查看

Description

Some of you may have played a game called 'Blocks'. There are n blocks in a row, each box has a color. Here is an example: Gold, Silver, Silver, Silver, Silver, Bronze, Bronze, Bronze, Gold.
The corresponding picture will be as shown below:




Figure 1

If some adjacent boxes are all of the same color, and both the box to its left(if it exists) and its right(if it exists) are of some other color, we call it a 'box segment'. There are 4 box segments. That is: gold, silver, bronze, gold. There are 1, 4, 3, 1 box(es) in the segments respectively.

Every time, you can click a box, then the whole segment containing that box DISAPPEARS. If that segment is composed of k boxes, you will get k*k points. for example, if you click on a silver box, the silver segment disappears, you got 4*4=16 points.

Now let's look at the picture below:




The first one is OPTIMAL.

Find the highest score you can get, given an initial state of this game.

Input

The first line contains the number of tests t(1<=t<=15). Each case contains two lines. The first line contains an integer n(1<=n<=200), the number of boxes. The second line contains n integers, representing the colors of each box. The integers are in the range 1~n.


Output

For each test case, print the case number and the highest possible score.


Sample Input

2
9
1 2 2 2 2 3 3 3 1
1
1


Sample Output

Case 1: 29
Case 2: 1


思路:

题目大意是给你一行方块,相同颜色可以消去,得分等于消去块数的平方,
求最大得分

先处理给你的序列,col[i]代表第i段的颜色,l[i]代表第i段的长度。
这是黑书的上的一道题,思路看过的人都会大呼巧妙!
三维数组 dp[x,y,k] 代表从第x段到第y段的最大得分,k为第j段后面
与第j段颜色相同的一段,可以不连续,但是可以消去(k的含义可能一时看不懂,没事 后面还有讲)。

对于第x段到第y段的最大得分,我们分成两种情况考虑。
1丶 先合并第j段,然后合并i到j-1段,

方程是 dp[i][j-0][0]+(l[j]+k)*(l[j]+k);
2丶 在x到y中找任意一段p,p与第j段颜色相同
合并p+1与j-1段,而p与j的颜色相同,所以可以看成一段即为p
如果用记忆化搜索,k那就是j的长度了,因为 记忆化是一个递归的过程嘛
但如果用dp方程转移的话 还需另做处理,要不复杂度为(o^4)....
方程是 dp[x][y][k]=max(dfs(i+1,y-1,0)+dfs(x,i,k+l[y]),)
只是dp的预处理不太懂 就不多解释了


记忆化搜索

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 250
using namespace std;
int len,l[MAXN],col[MAXN],T,n;
int dp[MAXN][MAXN][MAXN];
inline void read(int&x) {
x=0;int f=1;char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();}
x=x*f;
}
inline int dfs(int x,int y,int k) {
if(dp[x][y][k]) return dp[x][y][k];
if(x==y) return (l[y]+k)*(l[y]+k);
dp[x][y][k]=dfs(x,y-1,0)+(l[y]+k)*(l[y]+k);
for(int i=x;i<y;i++) {
if(col[i]==col[y])
dp[x][y][k]=max(dfs(i+1,y-1,0)+dfs(x,i,k+l[y]),dp[x][y][k]);
}
return dp[x][y][k];
}
int main() {
int x,t=0;
read(T);
while(T--) {
for(int i=1;i<=len;i++) col[i]=l[i]=0;
memset(dp,0,sizeof dp);
len=0;
read(n);
for(int i=1;i<=n;i++) {
scanf("%d",&x);
if(x==col[len]) l[len]++;
else {
len++;
l[len]=1;
col[len]=x;
}
}
t++;
printf("Case %d: ",t);
printf("%d\n",dfs(1,len,0));
}
}


DP转移

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#define Maxn 210
using namespace std;
int dp[Maxn][Maxn][Maxn],col[Maxn],len[Maxn],pre[Maxn],aper[Maxn],after[Maxn],vi[Maxn];
inline void read(int&x) {
x=0;int f=1;char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();}
x=x*f;
}
int main() {
int t,n,i,j,x,k,Case=0;
int cnt=0;
read(t);
while(t--){
memset(dp,0,sizeof(dp));
memset(pre,0,sizeof(pre));
memset(len,0,sizeof(len));
memset(aper,0,sizeof(aper));
cnt=0;
read(n);
for(i=1;i<=n;i++){
read(x);
if(x!=col[cnt])
col[++cnt]=x,len[cnt]=1,pre[cnt]=aper[x],aper[x]=cnt;
else
len[cnt]++;
}
memset(vi,0,sizeof(vi));
for(i=cnt;i>=1;i--){
if(vi[i]) continue;
after[i]=0;
int tmp=i;
for(j=i-1;j>=1;j--)
if(col[j]==col[tmp]){
after[j]=after[tmp]+len[tmp];
tmp=j;
vi[j--]=true;
}
}
int l;
for(l=0;l<=cnt;l++){
for(i=1;i+l<=cnt;i++){
j=i+l;
for(k=0;k<=after[j];k++){
dp[i][j][k]=dp[i][j-1][0]+(len[j]+k)*(len[j]+k);
int p=pre[j];
while(p>=i){
dp[i][j][k]=max(dp[i][j][k], dp[i][p][k+len[j]]+dp[p+1][j-1][0]);
p=pre[p];
}
}
}
}
printf("Case %d: %d\n",++Case,dp[1][cnt][0]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj dp