「区间DP」「洛谷PP3146 」[USACO16OPEN]248 G
[USACO16OPEN]248 G
题目:
题目描述
Bessie likes downloading games to play on her cell phone, even though she doesfind the small touch screen rather cumbersome to use with her large hooves.
She is particularly intrigued by the current game she is playing.The game starts with a sequence of NNN positive integers (2≤N≤2482 \leq N\leq 2482≤N≤248), each in the range 1…401 \ldots 401…40. In one move, Bessie cantake two adjacent numbers with equal values and replace them a singlenumber of value one greater (e.g., she might replace two adjacent 7swith an 8). The goal is to maximize the value of the largest numberpresent in the sequence at the end of the game. Please help Bessiescore as highly as possible!
给定一个1*n的地图,在里面玩2048,每次可以合并相邻两个(数值范围1-40),问最大能合出多少。注意合并后的数值并非加倍而是+1,例如2与2合并后的数值为3。
输入格式
The first line of input contains NNN, and the next NNN lines give the sequence
of NNN numbers at the start of the game.
输出格式
Please output the largest integer Bessie can generate.
输入输出样例
输入 #1
4
1
1
1
2
输出 #1
3
说明/提示
In this example shown here, Bessie first merges the second and third 1s to
obtain the sequence 1 2 2, and then she merges the 2s into a 3. Note that it is
not optimal to join the first two 1s.
思路:
受区间DP题单的影响,上来想分成两种状态分别讨论,向左向右预处理合并,之后区间DP割点合并。
代码实现如下:
/*#!/bin/sh
dir=$GEDIT_CURRENT_DOCUMENT_DIR
name=$GEDIT_CURRENT_DOCUMENT_NAME
pre=${name%.*}
g++ -O2 $dir/$name -o $pre -g -Wall -std=c++11
if test $? -eq 0; then
gnome-terminal -x bash -c "time $dir/$pre;echo;read;"
fi*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=505,INF=0x3f3f3f3f;
int n,f[2][maxn][maxn],a[maxn],m,ans;//1左0右
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
return s*w;
}
int main(){
n=read();
for(int i=1;i<=n;i++){a[i]=read(),f[0][i][i]=f[1][i][i]=a[i],ans=max(ans,a[i]);}//预处理f[0][i][i]和f[1][i][i]
for(int i=1;i<n;i++){
if(a[i]==a[i+1])f[0][i][i+1]=f[1][i][i+1]=a[i]+1;//相等合并
else f[0][i][i+1]=a[i+1],f[1][i][i+1]=a[i];
ans=max(ans,max(f[0][i][i+1],f[1][i][i+1]));
//cout<<i<<" "<<i+1<<" "<<f[0][i][i+1]<<endl;
}//预处理f[0][i][i+1]和f[1][i][i+1]
for(int d=3;d<=n;d++){
for(int i=1,j;(j=i+d-1)<=n;i++){
if(f[0][i][j-1]==a[j])f[0][i][j]=a[j]+1;//能合并就合并
else f[0][i][j]=a[j];//不能合并要改为最右端的数否则无法继续向右合并
if(f[1][i+1][j]==a[i])f[1][i][j]=a[i]+1;//同理
else f[1][i][j]=a[i];
ans=max(ans,max(f[1][i][j],f[0][i][j]));
//cout<<i<<" "<<j<<" "<<f[0][i][j]<<endl;
}
}//向右向左合并预处理
for(int d=2;d<=n;d++){//左右合并
for(int i=1,j;(j=i+d-1)<=n;i++){
for(int k=i;k<j;k++){
if(f[0][i][k]==f[1][k+1][j])f[0][i][j]=f[1][i][j]=f[0][i][k]+1;//两个区间内的数值相等就可以合并,因为保证了断点左右数值一定代表左右区间的数值,这也是用两个状态的原因
// else f[0][i][j]=f[]
ans=max(ans,max(f[1][i][j],f[0][i][j]));
}
}
}
cout<<ans;
}
调了二十分钟扔了,望有缘人能调出来。
后来康了一眼题解发现想多了。其实不用两个状态,而且只用上面代码的最后一个合并就行
断点左右区间数值相等就合并,价值+1,否则就为0
代码:
/*#!/bin/sh
dir=$GEDIT_CURRENT_DOCUMENT_DIR
name=$GEDIT_CURRENT_DOCUMENT_NAME
pre=${name%.*}
g++ -O2 $dir/$name -o $pre -g -Wall -std=c++11
if test $? -eq 0; then
gnome-terminal -x bash -c "time $dir/$pre;echo;read;"
fi*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=505,INF=0x3f3f3f3f;
int n,f[maxn][maxn],a[maxn],m,ans;//f[i][j]表示合并i-j的价值,当然如果i-j内不能合并,就为0,例如样例中f[3][4]=0
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
return s*w;
}
int main(){
//freopen("a.in","r",stdin);
n=read();
for(int i=1;i<=n;i++){a[i]=read(),f[i][i]=a[i],ans=max(ans,a[i]);}
for(int i=1;i<n;i++){
if(a[i]==a[i+1])f[i][i+1]=a[i]+1;
// else f[i][i+1]=0;
ans=max(ans,f[i][i+1]);
//cout<<i<<" "<<i+1<<" "<<f[0][i][i+1]<<endl;
}//预处理一模一样
for(int d=2;d<=n;d++){
for(int i=1,j;(j=i+d-1)<=n;i++){
for(int k=i;k<j;k++){//有k+1右端点肯定不能超过j
if(f[i][k]==f[k+1][j]&&f[i][k]!=0)f[i][j]=f[i][k]+1;//如果两个区间i-k和k+1-j内的数值相同,那就合并。
//但是有一要求:两个区间内的数值不能为0,即两个区间必须本身能合并
ans=max(ans,f[i][j]);
}
//cout<<i<<" "<<j<<" "<<f[i][j]<<endl;
}
}
cout<<ans;
}
over~
「区间DP」「洛谷PP3146 」[USACO16OPEN]248 G的更多相关文章
- 区间dp 能量项链 洛谷p1063
题目大意:如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为 (Mars单位),新产生的珠子的头标记为m,尾标记为n. 需要时,Mars人就用吸盘夹住 ...
- 「区间DP」「洛谷P1043」数字游戏
「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...
- 「区间DP」「洛谷P3205」「 [HNOI2010]」合唱队
洛谷P3205 [HNOI2010]合唱队 题目: 题目描述 为了在即将到来的晚会上有更好的演出效果,作为 A 合唱队负责人的小 A 需要将合唱队的人根据他们的身高排出一个队形.假定合唱队一共 n 个 ...
- 「洛谷5017」「NOIP2018」摆渡车【DP,经典好题】
前言 在考场被这个题搞自闭了,那个时候自己是真的太菜了.qwq 现在水平稍微高了一点,就过来切一下这一道\(DP\)经典好题. 附加一个题目链接:[洛谷] 正文 虽然题目非常的简短,但是解法有很多. ...
- Solution -「APIO 2016」「洛谷 P3643」划艇
\(\mathcal{Description}\) Link & 双倍经验. 给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...
- 「洛谷3870」「TJOI2009」开关【线段树】
题目链接 [洛谷] 题解 来做一下水题来掩饰ZJOI2019考炸的心情QwQ. 很明显可以线段树. 维护两个值,\(Lazy\)懒标记表示当前区间是否需要翻转,\(s\)表示区间还有多少灯是亮着的. ...
- 「洛谷5283」「LOJ3048」「十二省联考2019」异或粽子【可持久化01trie+优先队列】
题目链接 [洛谷传送门] [LOJ传送门] 题目大意 让你求区间异或和前\(k\)大的异或和的和. 正解 这道题目是Blue sky大佬教我做的(祝贺bluesky大佬进HA省A队) 我们做过某一些题 ...
- Solution -「洛谷 P4372」Out of Sorts P
\(\mathcal{Description}\) OurOJ & 洛谷 P4372(几乎一致) 设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...
- 「洛谷4197」「BZOJ3545」peak【线段树合并】
题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...
随机推荐
- 阿里云杨敬宇:边缘计算行业通识与阿里云ENS的技术演进之路
近日,阿里云杨敬宇在CSDN阿里云核心技术竞争力在线峰会上进行了<5G基础设施-阿里云边缘计算的技术演进之路>主题演讲,针对5G时代下,行业和技术的趋势.边缘计算产业通识以及阿里云边缘计算 ...
- jmeter 性能测试入门手册分享
深思熟虑之下,决定把这份性能测试入门手册分享给大家 最初整理这份教程的是因为自己在学习性能测试的过程中踩过了很多的坑,遇到了 数不清的问题,于是就想着将这些解决的问题全都归拢在一个文档里,方便自己查阅 ...
- 传递函数-微分方程-差分方程-Matlab阶跃响应曲线
Transfer function: 1 ------- 5 s + 1 写成微分方程: 5y'(t)+y(t)=u(t) 向前差分: 5y(k+1)+(T-5)y(k)=Tu(k) T:Sample ...
- matplotlib.pyplot.plot详解
参考资料: https://blog.csdn.net/baidu_41902768/article/details/80686608 之前的随笔也有说过,matplotlib是python中一个非常 ...
- 【JMeter_01】JMeter介绍与环境搭建
JMeter介绍 Apache JMeter™应用开源软件,100%纯Java应用程序,设计之初是用于负载功能测试和性能测试.但因它在实现对各种接口的调用方面比较成熟,因此,常被用做接口功能测试. J ...
- Day7-微信小程序实战-引入iconfont(充分利用iconfont图标库的资源)
一.引入iconfont 首先在iconfont.com中注册登陆: 点击上方[图标管理]并进入我的项目 注意:如果没有项目的话,就点击右边的来创建项目 在官网中找到想要的图标之后,以SVG的形式下载 ...
- IWAB0398E Error in generating WSDL from Java: java.lang.ClassNotFoundException
今天想用Eclipse创建WebService,报错信息 IWAB0398E Error in generating WSDL from Java: java.lang.ClassNotFoundEx ...
- 黎活明8天快速掌握android视频教程--24_网络通信之网页源码查看器
1 该项目的主要功能就是从将后台的html网页在Android的界面上显示出来 后台就是建立一个java web工程在工程尚建立一个html或者jsp文件就可以了,这里主要看Android客户端的程序 ...
- 尚硅谷 dubbo学习视频
1 1.搭建zookpeer注册中心 windows下载zooker 需要修改下zoo_sample .cfg为zoo.cnf 然后需要zoo.cnf中数据文件的路径 第五步:把zoo_sample ...
- vue element安装
element-ui插件 安装 >: cnpm i element-ui -S main.js配置 import ElementUI from 'element-ui'; import 'ele ...