poj 1390 Blocks
poj 1390 Blocks
题意
一排带有颜色的砖块,每一个可以消除相同颜色的砖块,,每一次可以到块数k的平方分数。问怎么消能使分数最大。。
题解
此题在徐源盛《对一类动态规划问题的研究》以及刘汝佳的黑书《算法艺术与信息学竞赛》中都有提及。
首先我们要将相同颜色块进行合并。定义状态\(dp[i][j][k]\)表示第\(i\)到第\(j\)个颜色块后面接了\(k\)个颜色为\(color[j]\)的砖块。
不难得出转移方程为\(dp[i][j][k]=max \{ dp[i][j-1][0]+(len[j]+k)^2, dp[i][p][k+len[j]] + dp[p+1][j][0] \}\)
我们可以记录一下上一次\(color[j]\)出现的位置,就可以在\(O(n^3)\)内完成问题。
此题我写的是递推,不过记忆化似乎更快
递推
#include <cstdio>
#include <cstring>
const int N = 205;
int dp[N][N][N], color[N], len[N], pre[N], pos[N];
inline void SelfMax(int &a, const int &b) { if (a < b) a = b; }
inline int p2(const int &a) { return a * a; }
int main() {
int n, pr, i, j, k, T, tot, a, Sizdp = sizeof dp, length, Case = 0;
scanf("%d", &T);
while (T--) {
n = 0; pr = -1; scanf("%d", &tot);
for (k = 1; k <= tot; ++k) {
scanf("%d", &a);
if (a != pr) color[++n] = pr = a, len[n] = 1;
else ++len[n];
}
memset(dp, 0, Sizdp); memset(pos, 0, sizeof pos);
for (i = 1; i <= n; ++i) pre[i] = pos[color[i]], pos[color[i]] = i;
for (length = 1; length <= n; ++length)
for (i = 1;; ++i) {
if ((j = i + length - 1) > n) break;
for (k = 0; k <= tot; ++k) {
dp[i][j][k] = dp[i][j-1][0] + p2(len[j] + k);
for (a = pre[j]; a >= i; a = pre[a])
SelfMax(dp[i][j][k], dp[i][a][k+len[j]] + dp[a+1][j-1][0]);
}
}
printf("Case %d: %d\n", ++Case, dp[1][n][0]);
}
return 0;
}
记忆化
#include <cstdio>
#include <cstring>
const int N = 205;
int dp[N][N][N], color[N], len[N], pre[N], pos[N], Sum[N];
inline void SelfMax(int &a, const int &b) { if (a < b) a = b; }
inline int p2(const int &a) { return a * a; }
int f(int i, int j, int k) {
if (~dp[i][j][k]) return dp[i][j][k];
if (i > j) return 0;
int &ret = dp[i][j][k];
ret = f(i, j-1, 0) + p2(k + len[j]);
for (int p = pre[j]; p >= i; p = pre[p]) SelfMax(ret, f(i, p, k + len[j]) + f(p+1, j - 1, 0));
return ret;
}
int main() {
int n, pr, i, j, k, T, tot, a, Sizdp = sizeof dp, length, Case = 0;
scanf("%d", &T);
while (T--) {
n = 0; pr = -1; scanf("%d",&tot);
for (k = 1; k <= tot; ++k) {
scanf("%d", &a);
if (a ^ pr) color[++n] = pr = a, len[n] = 1;
else ++len[n];
}
memset(dp, -1, Sizdp); memset(pos, 0, sizeof pos);
for (i = 1; i <= n; ++i) pre[i] = pos[color[i]], pos[color[i]] = i;
printf("Case %d: %d\n", ++Case, f(1, n, 0));
}
return 0;
}
poj 1390 Blocks的更多相关文章
- POJ 1390 Blocks(记忆化搜索+dp)
POJ 1390 Blocks 砌块 时限:5000 MS 内存限制:65536K 提交材料共计: 6204 接受: 2563 描述 你们中的一些人可能玩过一个叫做“积木”的游戏.一行有n个块 ...
- poj 1390 Blocks (经典区间dp 方块消除)
Blocks Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4250 Accepted: 1704 Descriptio ...
- POJ 1390 Blocks(区间DP)
Blocks [题目链接]Blocks [题目类型]区间DP &题意: 给定n个不同颜色的盒子,连续的相同颜色的k个盒子可以拿走,权值为k*k,求把所有盒子拿完的最大权值 &题解: 这 ...
- poj 1390 Blocks (记忆化搜索)
Blocks Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4318 Accepted: 1745 Descriptio ...
- POJ 1390 Blocks(DP + 思维)题解
题意:有一排颜色的球,每次选择一个球消去,那么这个球所在的同颜色的整段都消去(和消消乐同理),若消去k个,那么得分k*k,问你消完所有球最大得分 思路:显然这里我们直接用二位数组设区间DP行不通,我们 ...
- POJ 1390 Blocks (区间DP) 题解
题意 t组数据,每组数据有n个方块,给出它们的颜色,每次消去的得分为相同颜色块个数的平方(要求连续),求最大得分. 首先看到这题我们发现我们要把大块尽可能放在一起才会有最大收益,我们要将相同颜色块合在 ...
- 【POJ 1390】Blocks
http://poj.org/problem?id=1390 黑书上的例题,感觉我这辈子是想不到这样的dp了QAQ \(f(i,j,k)\)表示将\(i\)到\(j\)合并,并且假设未来会有\(k\) ...
- Blocks POJ - 1390 多维dp
题意:有一排box,各有不同的颜色.你可以通过点击某个box使得与其相邻的同色box全部消掉,然后你可以得到的分数为消去长度的平方,问怎样得到最高分? 题解:考虑用一维dp,/*dp[i]为1~i个b ...
- [POJ 3734] Blocks (矩阵高速幂、组合数学)
Blocks Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3997 Accepted: 1775 Descriptio ...
随机推荐
- 监控mysql各种选项
安装mysql之后,需要对mysql服务进行监控. nagios开源自带的check_mysql 对 mysql 的slave 机监控倒是不错.但是对数据库主机监控就略显不足了. 使用一个监控 ...
- mysql while,loop,repeat循环,符合条件跳出循环
1.while循环 DELIMITER $$ DROP PROCEDURE IF EXISTS `sp_test_while`$$ CREATE PROCEDURE `sp_test_while`( ...
- 网页实时聊天之PHP实现websocket
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- 【转】深入理解 Java 垃圾回收机制
深入理解 Java 垃圾回收机制 一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...
- Linux 多线程可重入函数
Reentrant和Thread-safe 在单线程程序中,整个程序都是顺序执行的,一个函数在同一时刻只能被一个函数调用,但在多线程中,由于并发性,一个函数可能同时被多个函数调用,此时这个函数就成了临 ...
- Linux shell 通配符 / glob 模式
概念 glob 模式(globbing)也被称之为 shell 通配符,名字的起源来自于 Unix V6 中的 /etc/glob (详见 man 文档).glob 是一种特殊的模式匹配,最常见的是通 ...
- 修改AndroidStudio中的Logcat中的默认设置
按Ctrl+Alt+S打开Settings 在左上角的输入框中输入Locat 点右边的使用内部样式取消掉,好了,开始自定义吧.
- nodejs缓冲模块buffer相关资料
buffer模块的详细使用教程 浅析nodejs的buffer类 深入浅出NodeJS--Buffer Node Buffer/Stream 内存策略分析
- [Django]模型提高部分--聚合(group by)和条件表达式+数据库函数
前言:本文以学习记录的形式发表出来,前段时间苦于照模型聚合中group by 找了很久,官方文章中没有很明确的说出group by,但在文档中有提到!!! 正文(最后编辑于2016-11-12): 聚 ...
- Java Generics and Collections-2.1
2.1 子类化以及替换原理 为什么List<Integer> 不是List<Number> 的子类? 首先看下面的代码,这段代码是编译不过的 package java_gene ...