poj 1390 较难的区间dp

poj 1390 Blocks(记忆化搜索/动态规划) 程序设计实习递归练习 Blocks 阅读详情

7月9日二更:突然发现一个神奇的事情,把代码写成这样会更快(110ms)(就是用临时变量ans代替f[l][r][elen]),可见全局变量的寻址时间还是比较长的

开O3优化,实际效果几乎等于0

int dp(int l, int r,int elen) {
	if (l == r)return (len[r] + elen) * (len[r] + elen);
	if (f[l][r][elen])return f[l][r][elen];

	int ans = dp(l, r - 1, 0) + (elen + len[r])*(elen + len[r]);
	for (int i = l; i <= r - 2; i++) 
		if (col[i] == col[r]) {
			ans = max(ans, dp(l, i, elen + len[r])
				+ dp(i + 1, r - 1, 0));
		}
		
	return f[l][r][elen] = ans;
}

网上的代码基本上都一样,都是从北大的算法课过来的。

题意:给你一个涂有颜色的方块的序列,每次你可以删除一些相同颜色并且相邻的颜色块,并获得删除数目平方的收益,现在给你一个颜色块序列,问收益最大值是多少?

Sample Input

2 //表示t
9 //n
1 2 2 2 2 3 3 3 1 //表示颜色
1
1
Sample Output

Case 1: 29
Case 2: 1

思路:
第一步先把方块合并成连续且颜色一样的大块,方便处理。

对于L到R区间的最优解,一般人可能会想,要么分成三截,先删除中间一节,然后期望两边的颜色一样,在删除两边的;或者直接从中间切成两截,然后求值。比较两种情况的最大值。

其实这种思路是有问题的,比如1 2 1 1 1 2 1 ,你可以分成五截,1 3 5截颜色一样,你可以先删除2 4 截,然后1 3 5 一起删,明显比上一种想法更优。

但你不可能枚举每中分截情况,所以你可以考虑先把右边的留着不删,假设dp(l,r,e)表示l,r区间的最大值,且之前还有e个方块没删,e的颜色和第r个方块颜色一样。

你有两种方案,第一种是把r和e一起删了,然后去计算dp(l,r-1,0);第二种是中间有个方块k和r同色,那么期望k和r+e合并在删,就是dp(l, k, e + len[r])+ dp(k+ 1, r - 1, 0)。dp(l, k, e + len[r])表示l到k区间的最优解,希望e+len[r]+len[k]可以继续往下合并,dp(k+ 1, r - 1, 0)就是k+1到r-1的最优解。

#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <stack>

#define INF 0x3f3f3f3f
#define IMAX 2147483646
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int

using namespace std;

int t, n, a[222],f[222][222][222],len[222],col[222],tot;

int dp(int l, int r,int elen) {
	if (l == r)return (len[r] + elen) * (len[r] + elen);
	if (f[l][r][elen])return f[l][r][elen];

	f[l][r][elen] = dp(l, r - 1, 0) + (elen + len[r])*(elen + len[r]);
	for (int i = l; i <= r - 2; i++) 
		if (col[i] == col[r]) {
			f[l][r][elen] = max(f[l][r][elen], dp(l, i, elen + len[r])
				+ dp(i + 1, r - 1, 0));
		}
		
	return f[l][r][elen];
}

int main() {
	scanf("%d", &t);
	for (int c = 1; c <= t; c++) {
		scanf("%d", &n);
		tot = 0;
		for (int i = 1; i <= n; i++) {
			scanf("%d", a + i);
			if (i == 1 || a[i] != a[i - 1]) {
				len[++tot] = 1;
				col[tot] = a[i];
			}
			else
				len[tot]++;
		}
		
		memset(f, 0, sizeof(f));
		printf("Case %d: %d\n", c, dp(1, tot,0));
	}
	
	return 0;
}

[POJ1390]Blocks(方块消除) 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, Go 阅读详情

相关推荐

POJ1390--blocks.rar

1390--blocks.rar

POJ_1390(三维动规)

POJ_1390,三维动规题目,按照大块分类,参考博客,重点: 1.构造递归函数 2.通过三维数组记忆化保存 #include<iostream> #include<cstring> #include<cstdio> using namespace std; struct Box{ int color,len; }box[205]; int t,n,x,...

宫·商的博客 460

数学不好是原罪——高等数学笔记(汇总版)

这是本人之前考研的高数手写笔记,工科学硕数一考了146(满分150),笔记有一定参考价值,欢迎大家收藏借鉴。

xuuyann 5万+

POJ 1390:Blocks

将Q与左边的某个大块k合并 score[i][j][len]=score[i][k][len+big[j].len]+score[k+1][j-1][0]一行有n个块,每个框都有一个颜色。将Q消去 score[i][j][len]=score[i][j-1][0]+(big[j].len+len)*(big[j].len+len)因此再考虑利用二维数组score[i][j]来表达状态,即代表第i个大块到第j个大块可以获得的最高分数,则与score[i][j-1]相比,可能。

weixin_74991413的博客 249

antiSMASH安装与使用

antiSMASH本地安装 简要: antiSMASH的本地安装需要安装很多的依赖包,本文章使用conda辅助安装 参考: 官方:https://docs.antismash.secondarymetabolites.org/install/ 文章:http://blog.sciencenet.cn/blog-3416913-1240614.html 依赖包下载 conda install -y diamond=0.8.36 conda install -y fasttree=2.1.9 conda ins

Curry_chenhu的博客 7224

Python + Google AI 自动修复 Sonar Bug 实践

在工作中总会遇到种种不期而至的需求,比如前段时间突然要修复所有 Sonar Bug,涉及各种琐碎的代码风格问题,包括但不限于语法不规范、废弃注释等问题。这些项目都已经持续开发几年了,Sonar 上的问题层出不穷,各种问题已经累积到了上万个,手动修复不但费时费力,而且过程异常枯燥。

子洋 Blog 2415

WinFrom真入门(1)——Windows窗体应用概念

用Winform开发的桌面程序,是在Windows操作系统上运行的,这个不用多说。窗体(Form)的作用‌:窗体是用户交互的容器,承载按钮、文本框等控件,构成应用程序的界面‌。在Windows操作系统中,窗体(窗口)所处可见,例如: 一个标准的窗体其实就是一块矩形区域,客户区域指的是窗口内部区域。除去标题兰和边框外的区域可视为内部区域,称为客户区域。我们开发人员可以在窗口的客户区域中放置控件,也可以在其中绘制出咱们所需要的图形。WinForm程序的项目的结构,如下图: Main()方法是程序的入口,这几行代

ByteGeek 1633

poj1390解题报告

题目大意:题意:给定n个不同颜色的盒子,连续的相同颜色的k个盒子可以拿走,权值为k*k,求把所有盒子拿完的最大权值。(有点像祖玛弹珠的即视感) 解题思路:据说是lrj大神黑书上的题,反正我后翻了别人的解题报告才做出来的 首先:合并初始相邻相同的块,得到颜色数组c和对应的长度len,例如 1 1 1 1 1 3 2 2 1 1 1 可记为color[ 1 ] = 1; len[1 ] = 5;

h123120的专栏 1578

AC7811无感FOC实战:从开环到闭环的电机控制调试全记录

本文详细记录了基于国产AC7811芯片实现无感FOC电机控制的全过程。从硬件软件环境搭建、开环I/F启动调试,到滑模观测器参数整定,再到平滑切入闭环及双环PID调节,提供了完整的实战步骤与参数调试心法。文章重点分享了无感控制从开环到闭环切换的关键技巧与常见问题排查清单,为工程师提供了一份避坑指南。

kotlin6android的博客 713

实战游戏项目管理1-规划篇

1、前言 做研发管理10多年,进游戏行业8年,经验下来项目管理就是一门技术,结合不同行业不同项目加以不同管理方法,但原理基本一样,这里总结下游戏项目的管理一些实操方法 一般游戏确定立项前都需要做,项目预研产出一个游戏Demo,通过公司的立项评审,这个过程的项目管理相对简单一般由制作人或其他项目经理兼任,只有控制好总体时间与成本就好,这里按立项后开始讲。 2、游戏项目规划 ...

pengdali的专栏 2万+

区间dp+三维状态,POJ1390 Blocks

比较难想的一个状态设计,当二维无法获取区间细节时,采取升维策略

EQUINOX1的博客 953

无人机巡检提速3倍!YOLOv8n+OpenVINO让Jetson Nano跑25FPS,还能多飞25分钟

摘要(149字): 针对无人机巡检中Jetson Nano算力不足导致的帧率低、首次推理延迟高、续航短等问题,提出YOLOv8n+OpenVINO联合优化方案: 模型轻量化:YOLOv8n参数量仅3.2M(较v8s减少71%),Jetson Nano帧率从8FPS提升至15FPS(原生),绝缘子裂纹召回率仅降3%; OpenVINO加速:AUTO模式动态分配CPU/GPU算力,首次推理延迟从500ms降至200ms,帧率再优化至25FPS; 能效提升:功耗降低40%,单次续航延长25分钟。方案已落地电力/林

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1242

poj1390 方块消除 dp

参考:徐源盛《对一类动态规划问题的研究》以及刘汝佳的黑书《算法艺术与信息学竞赛》 将方块序列,按颜色分成一段一段的,例如 1 1 1 1 1 3 2 2 1 1 1 可记为color[ 1 ] = 1; len[1 ] = 5; color[ 2 ] = 3; len[ 2 ]

2659

Maxwell个人初学经验及资料分享

前段时间学习了课题组基于Maxwell所建立的模型,因为以前从来没有使用过,只是按照一步一步记忆了操作,但总觉得不熟悉,我想是缺乏对这个软件整体的了解,真正想上手只会这一个模型也没有办法扩展。但是我感觉这些有限元分析软件学习起来应该有一些共性,基于以前对COMSOL学习的一点经验,我就在官网和其他网站找了一些学习资源构成一条基础入门之路,也可能有更好的资源,仅代表个人观点做一下分享。以上就是本人对该软件初步学习的一点理解,跟着这样的操作不到一个星期就能初步的掌握。...

怎么又是萝卜的博客 5631

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

POJ 1390 Blocks 区间dp

http://poj.org/problem?id=1390 https://www.acwing.com/problem/content/324/ 题意: n个木块排成一列,每个木块都有一个颜色。 每次,你都可以点击一个木块,这样被点击的木块以及和它相邻并且同色的木块就会消除。 如果一次性消除了k个木块,那么就会得到k*k分。 给定你一个游戏初始状态,请你求出最高得分是多少 输入格...

forOnward的博客 254

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

POJ-1390-Blocks (复杂区间DP)

\(POJ~1390~~Blocks:\) (很难想的区间DP) \(solution:\) 很好的一道题目。看起来似乎很简单,当时一直认为可以用二维区间DP来完成,转移 \(n^3\)。 后来发现如果用二维表示当前状态,转移可以说无路可走。因为可能存在原本不相邻的多个区间最后是一起消除的。所以我们需要保留下来某一段重复的区间做为我们的一个新的维度。 或者说,(存在原本不相邻的多个区间最后...

weixin_30535565的博客 179

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

POJ 1390 Blocks 区间DP

区间DP的核心:把大区间分解成相同规模的小区间,小区间返回子结构的值给大区间从而得到最优解。但是怎么就能根据不同的题模拟出特定的比较合适的子结构呢?我觉得与其说这是一种编码的熟练度问题,不如说是对实际问题建模的敏感度问题。如何设计优秀的子结构问题真的很考验一个人的最基本最核心的创造力和分析能力,刷题套模板真的能整出来吗。。。 就拿这个题来说,可以很轻易的想到dp[i][j]为i到j区间的最优值,...

lizhenhao 244

蓝书(算法竞赛进阶指南)刷题记录——POJ1390 Blocks(区间DP+记忆化搜索)

题目:POJ1390. 题目大意:给定一个长度为nnn的序列,每次可以删除权值相同连续一段且得分为长度的平方,求最大得分. 数据组数≤15\leq 15≤15,1≤n≤2001\leq n\leq 2001≤n≤200. 按照区间DP的套路,设f[l][r]f[l][r]f[l][r]表示区间[l,r][l,r][l,r]的答案,发现根本没办法转移. 考虑无法转移的原因是什么,我们发现在转移的时候...

hzk_cpp的博客 314

POJ 1390 Blocks (区间DP) 题解

题意 t组数据,每组数据有n个方块,给出它们的颜色,每次消去的得分为相同颜色块个数的平方(要求连续),求最大得分。 首先看到这题我们发现我们要把大块尽可能放在一起才会有最大收益,我们要将相同颜色块合在一起,我们可以分区间进行处理,便可用区间dp解决,我们尝试合并区间我们定义状态f[i][j]表示合并i-j这个区间的最大得分,那么状态转移方程便可写为 f[i][j]=max(f[i][j]...

aqg41577的博客 265

【POJ 1390】Blocks

http://poj.org/problem?id=1390 黑书上的例题,感觉我这辈子是想不到这样的dp了QAQ \(f(i,j,k)\)表示将\(i\)到\(j\)合并,并且假设未来会有\(k\)个与\(a_j\)同色的方块与\(j\)相连的最大得分。 如果直接消去第\(j\)个区域和未来会接到\(j\)后面的\(k\)块,那么 \(f(i,j,k)=f(i,j-1,0)+(b_j+...

as2886089的博客 182

poj 1390 Blocks(dp,黑书dp方块消除)

poj 1390 Blocks

yjCola 978

poj1390 Blocks(经典区间dp/消除问题)

题目 思路来源 https://www.cnblogs.com/Tieechal/p/11637638.html清楚明白的讲解 题解 和[Luogu2135] 方块消除及UVA10559 Blocks是一模一样的题目 代码 #include<iostream> #include<cstdio> #include<cstring> us...

小衣同学的博客 610

[题]Blocks #区间DP

这是详解,贼长。详解博客 简单点说,自己看代码理解。 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 220; int t, n, a, co[N], cnt, f[N][N][N], len[N]; int read() { int ret = 0; char ch = getchar(); while (.

仅仅是笔记。 85

poj 1390 Blocks

<br />//poj 1390 解法很巧妙,见lrj黑书。。。<br />#include <iostream><br />#include <algorithm><br />using namespace std;<br /><br />int n,m;<br />int color[205],len[205];<br />int dp[205][205][205];<br />int after[205];<br />int main()<br />{<br />    int t,a;<br /> 

birdforever的专栏 914

【poj1390】Blocks【区间dp】

传送门 一道很nice的题。首先肯定将颜色相同的缩点,因为中间不可能插进去不同的。 首先可以很明白的看出是区间动态规划。但是接下来我们发现不太清楚怎么转移,因为中间和两边选的顺序可能不一样。 我们考虑最右边这个大联通块有多少个颜色一样的。因为有些可能是别人并过来的。 然后策略就分两种。一种是直接把最右边的吃了。另一种是把中间的吃了然后把右边的弄过来整成一块。 设f(l,r,k)表示这个区...

gigo_64 sink in my world 146
上一篇: poj 1191
下一篇: poj 1463 简单树状dp
FawkesLi
博客等级 码龄8年 21粉丝 170原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值