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:



Figure 2

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 对于贪心显然就不正确了;
那么考虑dp;
设dp[ i ][ j ][ k ]表示i~j区间,最后合并k个的最大值;
dp[ i ][ j ][ k ]=dp[ i ][ j-1 ][ 0 ]+( len[ j ]+k )^2;
第二种情况就是中间一段先消去,然后与后面那一段拼接消除;
dp[ i ][ j ][ k ]=dp[ i ][ k ][ len[ j ]+k ]+dp[ k+1 ][ j-1 ][ 0 ];
那么我们记忆化dfs即可;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize(2)
using namespace std;
#define maxn 400005
#define inf 0x7fffffff
//#define INF 1e18
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef pair<int, int> pii;
inline ll rd() {
ll x = 0;
char c = getchar();
bool f = false;
while (!isdigit(c)) {
if (c == '-') f = true;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f ? -x : x;
} ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; } /*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1; y = 0; return a;
}
ans = exgcd(b, a%b, x, y);
ll t = x; x = y; y = t - a / b * y;
return ans;
}
*/ ll mode;
struct matrix {
ll n, m, a[10][10];
matrix(ll n, ll m) {
this->n = n; this->m = m; ms(a);
}
matrix(ll n, ll m, char c) {
this->n = n; this->m = m; ms(a);
for (int i = 1; i <= n; i++)a[i][i] = 1;
}
ll *operator [](const ll x) {
return a[x];
}
matrix operator *(matrix b) {
matrix c(n, b.m);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= b.m; j++) {
for (int k = 1; k <= m; k++) {
c[i][j] = (c[i][j] + a[i][k] % mode*b[k][j] % mode) % mode;
}
}
}
return c;
}
void operator *=(matrix &b) {
*this = *this *b;
}
matrix operator ^(ll b) {
matrix ans(n, m, 'e'), a = *this;
while (b) {
if (b % 2)ans = ans * a; a *= a; b >>= 1;
}
return ans;
}
}; int dp[202][202][202];
int T;
int n;
int col[210];
int len[202];
int fg;
int dfs(int x, int y, int k) {
if (dp[x][y][k])return dp[x][y][k];
if (x == y)return (len[x] + k)*(len[x] + k);
dp[x][y][k] = dfs(x, y - 1, 0) + (len[y] + k)*(len[y] + k);
for (int i = x; i < y; i++) {
if (col[i] == col[y]) {
dp[x][y][k] = max(dp[x][y][k], dfs(x, i, len[y] + k) + dfs(i + 1, y - 1, 0));
}
}
return dp[x][y][k];
} int main()
{
//ios::sync_with_stdio(0);
rdint(T); int cnt = 0;
while (T--) {
cnt++;
ms(dp); ms(col); ms(len);
fg = 0;
int ans = 0;
rdint(n);
for (int i = 1; i <= n; i++) {
int tmp; rdint(tmp);
if (col[fg] == tmp)len[fg]++;
else fg++, len[fg] = 1, col[fg] = tmp;
}
ans = dfs(1, fg, 0);
cout << "Case " << cnt << ": " << ans << endl;
}
return 0;
}

Blocks poj 区间dp的更多相关文章

  1. Blocks题解(区间dp)

    Blocks题解 区间dp 阅读体验...https://zybuluo.com/Junlier/note/1289712 很好的一道区间dp的题目(别问我怎么想到的) dp状态 其实这个题最难的地方 ...

  2. 【Uva10559】Blocks(区间DP)

    Description 题意:有一排数量为N的方块,每次可以把连续的相同颜色的区间消除,得到分数为区间长度的平方,然后左右两边连在一起,问最大分数为多少. \(1\leq N\leq200\) Sol ...

  3. UVA10559 方块消除 Blocks(区间dp)

    一道区间dp好题,在GZY的ppt里,同时在洛谷题解里看见了Itst orz. 题目大意 有n个带有颜色的方块,没消除一段长度为 \(x\) 的连续的相同颜色的方块可以得到 \(x^2\) 的分数,用 ...

  4. POJ 1390 Blocks(区间DP)

    Blocks [题目链接]Blocks [题目类型]区间DP &题意: 给定n个不同颜色的盒子,连续的相同颜色的k个盒子可以拿走,权值为k*k,求把所有盒子拿完的最大权值 &题解: 这 ...

  5. POJ 1390 Blocks (区间DP) 题解

    题意 t组数据,每组数据有n个方块,给出它们的颜色,每次消去的得分为相同颜色块个数的平方(要求连续),求最大得分. 首先看到这题我们发现我们要把大块尽可能放在一起才会有最大收益,我们要将相同颜色块合在 ...

  6. 【POJ-1390】Blocks 区间DP

    Blocks Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5252   Accepted: 2165 Descriptio ...

  7. POJ1390 Blocks (区间DP)

    题目链接:POJ 1390.Blocks 题意: 有n个方块排成一列,每个方块有颜色即1到n的一个值,每次操作可以把一段相同颜色的方块拿走,长度为k,则获得的分数为 \(k\times k\),求可获 ...

  8. UVA10559&POJ1390 Blocks 区间DP

    题目传送门:http://poj.org/problem?id=1390 题意:给出一个长为$N$的串,可以每次消除颜色相同的一段并获得其长度平方的分数,求最大分数.数据组数$\leq 15$,$N ...

  9. POJ 1179 - Polygon - [区间DP]

    题目链接:http://poj.org/problem?id=1179 Time Limit: 1000MS Memory Limit: 10000K Description Polygon is a ...

随机推荐

  1. 【Android 多媒体应用】使用 TTS

    import java.util.Locale; import android.app.Activity; import android.os.Bundle; import android.speec ...

  2. DAY19-上传头像并预览

    一个简单的注册页面: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  3. Android添加Menu菜单

    在安卓中添加Menu菜单十分简单. 步骤: 1.在menu文件夹中的main.xml文件中添加要添加的项目. <menu xmlns:android="http://schemas.a ...

  4. Android 图片相关

    从asset文件夹中读取Bitmap //从asset文件夹中取文件 private Bitmap getImageFromAssetFile(String fileName){ Bitmap ima ...

  5. memset,memcpy,strcpy的使用与区别

    1.memset 原型:   extern void *memset(void *buffer, int c, int count); 功能:   把buffer所指内存区域的前count个字节设置成 ...

  6. day17-jdbc 6.Connection介绍

    package cn.itcast.jdbc; import com.mysql.jdbc.Connection; import java.sql.DriverManager; import java ...

  7. 解决iText+freemark导出pdf不支持base64的解决办法

    工具类: package test; import java.io.IOException ; import org.w3c.dom.Element ; import org.xhtmlrendere ...

  8. c语言学习笔记 const变量

    在c语言的编程过程中经常会遇到有常数参加运算的运算,比如这种. int a=100*b; 这个100我们叫常数或者叫常量,但是程序中我们不推荐这种直接写常数的方法,有两个缺点. 第一是程序可读性差. ...

  9. php学习笔记-默认参数

    在定义函数的时候,我们可以把其中的一个参数变的特殊起来,使它有一个默认值,这个参数就叫默认参数.在调用这个函数的时候,你既可以给这个默认参数传递一个值,这样的话默认参数的值会被覆盖掉,也可以不给它传递 ...

  10. 前端(HTML/CSS/JS)-CSS编码规范

    1. 文件名规范 文件名建议用小写字母加中横线的方式.为什么呢?因为这样可读性比较强,看起来比较清爽 https://stackoverflow.com/questions/25704650/disa ...