Blocks题解(区间dp)
Blocks题解
区间dp
阅读体验。。。https://zybuluo.com/Junlier/note/1289712
很好的一道区间dp的题目(别问我怎么想到的)
dp状态
其实这个题最难的地方是这道题目的状态怎么设
- 首先既然是区间dp,那肯定最先想到的状态是
\(dp[i][j]\)表示消掉区间\([i,j]\)上所有的块的最大分数
突然发现这个状态会受区间外和\(i\)或\(j\)颜色相同的块的影响
并且转移也并不好转移=_=所以我们考虑换一种状态。。。
既然说会受到外面的块的影响?那考虑一种方法来解决
\(dp[i][j][k]\)表示消掉区间\([i,j]\)并且区间\([i,j]\)右边还有k个和j颜色相同的块(除此之外,这个序列没有别的块了),消掉这些所有的块的最大分数
有点抽象,再来感性理解一下:
当前处理的子问题\(dp[i][j][k]\)主体由区间\([i,j]\)组成,然后与\(j\)相同有\(k\)块接在后面,这\(k\)块之间的其他块已经全部消完了
- 如果实在还不明白,先看转移吧。。。
然后可以根据我们前面的错误状态自己思考为什么加上这一维
转移
\(dp[i][j][k]\):显然有两种转移
我这里是用记忆化搜索实现的
- 消掉j和后面的k块
```
dp[i][j][k]=max(dp[i][j][k],Dfs(i,j-1,0)+(k+1)*(k+1));
```
- 对于区间\([i,j]\),中间可能有和\(j\)颜色相同的块,假设位置为\(p\),我们可以选择消掉区间\([p+1,j-1]\)中所有的块使颜色拼起来,当然这是个子问题,所以前面讲了用记忆化搜索实现
PS: 下面代码的\(nxt[p]\)是预处理的在\(p\)前面第一个和\(p\)颜色相同的块的位置
```
for(int p=nxt[j];p>=i;p=nxt[p])//枚举p
dp[i][j][k]=max(dp[i][j][k],Dfs(i,p,k+1)+Dfs(p+1,j-1,0));
```
汇总
讲完这些整个程序的实现就不难了
那我直接放上代码,不好意思,没有注释
#include<bits/stdc++.h>
#define lst long long
#define ldb double
#define N 250
using namespace std;
const int Inf=1e9;
int read()
{
int s=0,m=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')m=1;ch=getchar();}
while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return m?-s:s;
}
int n;
int col[N],nxt[N],hd[N];
lst dp[N][N][N];//消掉[i,j]区间和[i,j]右边和j颜色一样的连续k个方块的最大分数
lst Dfs(int i,int j,int k)
{
if(i>j)return 0;
if(dp[i][j][k])return dp[i][j][k];
dp[i][j][k]=max(dp[i][j][k],Dfs(i,j-1,0)+(k+1)*(k+1));
for(int p=nxt[j];p>=i;p=nxt[p])
dp[i][j][k]=max(dp[i][j][k],Dfs(i,p,k+1)+Dfs(p+1,j-1,0));
return dp[i][j][k];
}
int main()
{
int T=read();
for(int tt=1;tt<=T;++tt)
{
n=read();
memset(hd,0,sizeof(hd));
memset(dp,0,sizeof(dp));
memset(nxt,0,sizeof(nxt));
for(int i=1;i<=n;++i)
{
col[i]=read();
nxt[i]=hd[col[i]];
hd[col[i]]=i;
}
printf("Case %d: %lld\n",tt,Dfs(1,n,0));
}
return 0;
}
Blocks题解(区间dp)的更多相关文章
- UVA10559 方块消除 Blocks(区间dp)
一道区间dp好题,在GZY的ppt里,同时在洛谷题解里看见了Itst orz. 题目大意 有n个带有颜色的方块,没消除一段长度为 \(x\) 的连续的相同颜色的方块可以得到 \(x^2\) 的分数,用 ...
- luogu1005矩阵取数游戏题解--区间DP
题目链接 https://www.luogu.org/problemnew/show/P1005 分析 忽然发现这篇题解好像并没有什么意义...因为跟奶牛零食那道题一模一样,博主比较懒如果您想看题解的 ...
- 【Uva10559】Blocks(区间DP)
Description 题意:有一排数量为N的方块,每次可以把连续的相同颜色的区间消除,得到分数为区间长度的平方,然后左右两边连在一起,问最大分数为多少. \(1\leq N\leq200\) Sol ...
- luogu2858奶牛零食题解--区间DP
题目链接 https://www.luogu.org/problemnew/show/P2858 一句话题意: https://cn.vjudge.net/problem/POJ-3186#autho ...
- luogu4302字符串折叠题解--区间DP
题目链接 https://www.luogu.org/problemnew/show/P4302 分析 很明显一道区间DP题,对于区间\([l,r]\)的字符串,如果它的字串是最优折叠的,那么它的最优 ...
- 洛谷P1220 关路灯 题解 区间DP
题目链接:https://www.luogu.com.cn/problem/P1220 本题涉及算法:区间DP. 我们一开始要做一些初始化操作,令: \(p[i]\) 表示第i个路灯的位置: \(w[ ...
- Blocks poj 区间dp
Some of you may have played a game called 'Blocks'. There are n blocks in a row, each box has a colo ...
- 2017 ACM-ICPC亚洲区域赛北京站J题 Pangu and Stones 题解 区间DP
题目链接:http://www.hihocoder.com/problemset/problem/1636 题目描述 在中国古代神话中,盘古是时间第一个人并且开天辟地,它从混沌中醒来并把混沌分为天地. ...
- luogu4677山区建小学题解--区间DP
题目链接 https://www.luogu.org/problemnew/show/P4677 分析 这道题方法跟之前题不一样,我们相当于枚举一个左右端点来线性扩展,同时划分断点进行决策 \(f[i ...
随机推荐
- ElasticSearch 入门介绍
tags: 第三方 lucene [toc] 1. what Elastic Search(ES)是什么 全文检索和lucene 全文检索 优点:高效,准确,分词全文检索允许用户输入一些关键字,从数据 ...
- java 类加载及实例化的调用顺序
1.没有继承的情况 单独一个类的场景下,初始化顺序为依次为 静态变量和静态代码块(看两者的书写顺序),继承的基类的构造函数,成员变量,被调用的构造函数. 代码呈现: public class Test ...
- liunx-centos-基础命令详解(1) -主要内容来自 —https://www.cnblogs.com/caozy/p/9261224.html
关机:halt/poweroff :立刻关机reboot :立刻重启 shutdown -r now :立刻重启shutdown -h 00:00 :定时重启 now:立刻shutdown -h +n ...
- 伪类和伪元素,review
总是分不太清楚,然后容易忘记这个概念,项目中又遇到了,复习一遍 问题 1.哪些常用的伪类?伪元素? 怎么记: 除了4个伪元素,其他都是伪类 哪四个伪元素?:before :after :first-l ...
- Java8 时间处理类的使用实践(LocalDate...)
有了它,谁还在用Date?Calendar? 其实也不能这么绝对,毕竟还没到那个程度上.Java8 新增了处理时间的一组类(LocalDate.LocalDateTime.LocalTime),刚开始 ...
- js实时计算价格
//通过数量,单价的输入,实时显示总价 $("#number,#price").on("input",function(e){ $("#totalPr ...
- bzoj1875 [SDOI2009]HH去散步 矩阵快速幂
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1875 题解 如果没有这个"不能立刻沿着刚刚走来的路走回",那么这个题就是一 ...
- MTV和MVC的区别
著名的MVC模式:方便解藕 所谓的MVC就是把web应用分为三层 1.模型层: model 负责业务对象和数据库的对象(ORM)的映射 2.视图层 views 负责与用户的交互(书 ...
- [POJ 1911] 棋盘
问题描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着 ...
- python之面向过程,函数式编程,面向对象浅析
python编程有面向过程.面向函数.面向对象三种,那么他们区别在哪呢?这个问题,让我想起我在学习编程的时候,我的老师给我举的例子.分享给大家. 面向过程就是将编程当成是做一件事,要按步骤完成! 比如 ...