[POJ 1390] Blocking
问题描述
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:

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 kk points. for example, if you click on a silver box, the silver segment disappears, you got 44=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.
输入格式
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.
输出格式
For each test case, print the case number and the highest possible score.
样例输入
2
9
1 2 2 2 2 3 3 3 1
1
1
样例输出
Case 1: 29
Case 2: 1
题意概括
给定一个序列,每次可以消去一个均为同种元素的区间,若区间长度为k,则将会获得k*k的分数。求最大可以获得的分数。
解析
显然这是一道区间动态规划的题目,可以用记忆化搜索的方式去实现。首先,我们可以用\(l\)和\(r\)表示区间的范围。但是,仅由此还不够进行状态转移,因为还需要一个变量来衡量连续区间的长度。我们的突破口是每一个状态子区间的独立性。
对于一个子区间\([l,r]\),想要消去这个区间就只有两个办法:一是消去与r相邻的所有相同颜色的方块,再消去区间\([l,r-1]\);二是找到在\([l,r]\)中的某个位置\(k\)使\(r\)和\(k\)颜色相同,消去区间\([k+1,r-1]\)使相同色块拼在一起后再一同消去,然后消去区间\([l,k-1]\)。这样做的依据就是前面提到的独立性。对于任何一个区间,目标都只是消去该区间,而不用管其他的区间。区间内部则由区间的相互独立的子区间决定。这就说明了下面的方程中0的出现。
综上所述,设\(f[l][r][k]\)表示在区间\([l,r]\)右边与\(r\)同色的有\(k\)块时消去该区间(包括右边相同的部分)的最优解。我们可以得到如下状态转移方程:
\]
其中\(l<=i<=r,col[i]=col[r]\)。为了题目需要,我们还需要记录每个色块前面第一个和自己相同的颜色。这个可以借鉴图论中邻接表的思想来实现。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#define N 202
using namespace std;
int t,n,i,a[N],f[N][N][N],nxt[N],head[N],cnt;
int dp(int l,int r,int k)
{
if(l>r) return 0;
if(f[l][r][k]!=0) return f[l][r][k];
f[l][r][k]=max(f[l][r][k],dp(l,r-1,0)+(k+1)*(k+1));
for(int i=nxt[r];i>=l;i=nxt[i]){
f[l][r][k]=max(f[l][r][k],dp(l,i,k+1)+dp(i+1,r-1,0));
}
return f[l][r][k];
}
int main()
{
cin>>t;
while(t--){
cnt++;
cin>>n;
memset(f,0,sizeof(f));
memset(head,0,sizeof(head));
memset(nxt,0,sizeof(nxt));
for(i=1;i<=n;i++){
cin>>a[i];
nxt[i]=head[a[i]];
head[a[i]]=i;
}
cout<<"Case "<<cnt<<": "<<dp(1,n,0)<<endl;
}
}
[POJ 1390] Blocking的更多相关文章
- poj 1390 Blocks
poj 1390 Blocks 题意 一排带有颜色的砖块,每一个可以消除相同颜色的砖块,,每一次可以到块数k的平方分数.问怎么消能使分数最大.. 题解 此题在徐源盛<对一类动态规划问题的研究&g ...
- POJ 1390 Blocks(记忆化搜索+dp)
POJ 1390 Blocks 砌块 时限:5000 MS 内存限制:65536K 提交材料共计: 6204 接受: 2563 描述 你们中的一些人可能玩过一个叫做“积木”的游戏.一行有n个块 ...
- 【POJ 1390】Blocks
http://poj.org/problem?id=1390 黑书上的例题,感觉我这辈子是想不到这样的dp了QAQ \(f(i,j,k)\)表示将\(i\)到\(j\)合并,并且假设未来会有\(k\) ...
- poj 1390 区间dp
Blocks Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5035 Accepted: 2065 Descriptio ...
- poj 1390 Blocks (经典区间dp 方块消除)
Blocks Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4250 Accepted: 1704 Descriptio ...
- POJ 1390 Block
Description 给你一堆块,每个块有颜色,每次可以消去相邻颜色块,并获得块大小平方的分数,求最高得分. Sol DP/记忆化搜索. \(f[i][j][k]\) 表示 \((i,j)\) 这个 ...
- poj 1390 动态规划
思路: 黑书的例题 #include<iostream> #include<cstring> #include<algorithm> #include<cma ...
- POJ 1390 Blocks(区间DP)
Blocks [题目链接]Blocks [题目类型]区间DP &题意: 给定n个不同颜色的盒子,连续的相同颜色的k个盒子可以拿走,权值为k*k,求把所有盒子拿完的最大权值 &题解: 这 ...
- POJ 1390 Blocks(DP + 思维)题解
题意:有一排颜色的球,每次选择一个球消去,那么这个球所在的同颜色的整段都消去(和消消乐同理),若消去k个,那么得分k*k,问你消完所有球最大得分 思路:显然这里我们直接用二位数组设区间DP行不通,我们 ...
随机推荐
- UEFI手札
基于Intel TianoCore衍生的EDK-II诞生的UEFI,用来取代Legacy BIOS. INF文件 Module Information File,模块描述文件.Module可以是可执行 ...
- WebRtc 源码下载
项目需要用到WebRtc,记录下基本下载的步骤: 1.下载depot_tools,利用depot_tools 下载WebRtc源码 git clone https://chromium.googles ...
- Delphi XE2 之 FireMonkey 入门(21) - 和 FMX 相关的类(表)
TObject TPersistent TComponent IInterface,IInterfaceComponentReference TBasicAction TControl ...
- 阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第7节 Arrays工具类_16_数组工具类Array
在java.util的包下面.在这个包的下面是需要导包的,只有lang 的包下面是不需要导包的 查看jdk1.6的手册 Arrays让我们想起了数组,说明它提供了与数组相关的方法 我们可以看到 toS ...
- list、tuple、dict加*星号
*相当于解压的作用,当list中只有一个元素时,利用*作用相当于直接去[],去[]后的数据类型是字符串. _list = [1,2,3] _tuple = (1,2,3) _dict = {1:'a' ...
- uni-app-小程序中组件不支持id选择器等
这个问题刚开始遇到的时候有点搞笑啰,正常情况下,id选择器不是最正常的吗?搞锤子哦. 接着我就找度娘了 ,官网给出的解释是:https://developers.weixin.qq.com/mini ...
- SpringBoot中FreeMarker创建
1.创建SpringBoot项目时,勾选freemarker依赖(web,dev) 2.Controller中向model中存放数据 package com.ziv.springbootbygrald ...
- display:table
display:table的CSS声明能够让一个HTML元素和它的子节点像table元素一样.使用基于表格的CSS布局,使我们能够轻松定义一个单元格的边界.背景等样式,而不会产生因为使用了table那 ...
- BZOJ 1875(DP+矩阵快速幂)
题面 传送门 分析 容易想到根据点来dp,设dp[i][j]表示到i点路径长度为j的方案数 状态转移方程为dp[i][k]=∑(i,j)∈Edp[j][k−1]" role="pr ...
- Python 中的 os 模块常见方法?
os.remove() 删除文件 os.rename() 重命名文件 os.walk() 生成目录树下的所有文件名 os.chdir() 改变目录 os.mkdir/makedirs 创建目录/多层目 ...