[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的更多相关文章

  1. 区间dp 能量项链 洛谷p1063

    题目大意:如果前一颗能量珠的头标记为m,尾标记为r,后一颗能量珠的头标记为r,尾标记为n,则聚合后释放的能量为 (Mars单位),新产生的珠子的头标记为m,尾标记为n. 需要时,Mars人就用吸盘夹住 ...

  2. 「区间DP」「洛谷P1043」数字游戏

    「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...

  3. 「区间DP」「洛谷P3205」「 [HNOI2010]」合唱队

    洛谷P3205 [HNOI2010]合唱队 题目: 题目描述 为了在即将到来的晚会上有更好的演出效果,作为 A 合唱队负责人的小 A 需要将合唱队的人根据他们的身高排出一个队形.假定合唱队一共 n 个 ...

  4. 「洛谷5017」「NOIP2018」摆渡车【DP,经典好题】

    前言 在考场被这个题搞自闭了,那个时候自己是真的太菜了.qwq 现在水平稍微高了一点,就过来切一下这一道\(DP\)经典好题. 附加一个题目链接:[洛谷] 正文 虽然题目非常的简短,但是解法有很多. ...

  5. Solution -「APIO 2016」「洛谷 P3643」划艇

    \(\mathcal{Description}\)   Link & 双倍经验.   给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...

  6. 「洛谷3870」「TJOI2009」开关【线段树】

    题目链接 [洛谷] 题解 来做一下水题来掩饰ZJOI2019考炸的心情QwQ. 很明显可以线段树. 维护两个值,\(Lazy\)懒标记表示当前区间是否需要翻转,\(s\)表示区间还有多少灯是亮着的. ...

  7. 「洛谷5283」「LOJ3048」「十二省联考2019」异或粽子【可持久化01trie+优先队列】

    题目链接 [洛谷传送门] [LOJ传送门] 题目大意 让你求区间异或和前\(k\)大的异或和的和. 正解 这道题目是Blue sky大佬教我做的(祝贺bluesky大佬进HA省A队) 我们做过某一些题 ...

  8. Solution -「洛谷 P4372」Out of Sorts P

    \(\mathcal{Description}\)   OurOJ & 洛谷 P4372(几乎一致)   设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...

  9. 「洛谷4197」「BZOJ3545」peak【线段树合并】

    题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...

随机推荐

  1. 浅谈js原型

    前言 突发奇想,想写一篇原型的文章,也可能是因为对原型有更深的理解吧,在这里做个记录,来记录下自己的理解加深下记忆. 总之,希望本文的内容能够对您的学习或者工作有所帮助.另,如果有任何的错误或者不足请 ...

  2. 钻进 Linux 内核看个究竟

    Linux 内核,这个经常听见,却不不知道它具体是干嘛的东西,是不是觉得非常神秘? Linux 内核看不见摸不着,而对于这类东西,我们经常无从下手.本文就以浅显易懂的语言,带你钻进 Linux 内核, ...

  3. tensorflow2.0学习笔记第二章第四节

    2.4损失函数损失函数(loss):预测值(y)与已知答案(y_)的差距 nn优化目标:loss最小->-mse -自定义 -ce(cross entropy)均方误差mse:MSE(y_,y) ...

  4. Java 切割字符串的几种方式

    按效率排: 1.StringTokenizer切割 是java.util中的一个类,包含的api有: StringTokenizer的方法请参考上一篇. 其中,countTokens为length:n ...

  5. 织梦cms 内容模型 option下拉框 value 分离

    需要修改的文件在根目录include/customfields.func.php文件 foreach($items as $v) { $v = trim($v); if($v!='') { $myfo ...

  6. <Android> Location Service 分析

    由于各种原因,老师希望我学习Android系统源码以应对可能参与的项目.我只好深入曹营,刺探军情了. 定位服务是手机上最常用的功能之一,据说也是相对比较简单的服务,所以从这里入手.其他系统服务的架构都 ...

  7. @luogu - P6109@ [Ynoi2009]rprmq

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有一个 n×n 的矩阵 a,初始全是 0,有 m 次修改操作和 ...

  8. Unit2-窝窝牌电梯

    全文共2329字,推荐阅读时间10~15分钟. 文章共分四个部分: 作业分析 评测相关 重构策略 课程体验感受 作业分析 Unit2要求我们模拟现实生活中的电梯调度情景,迭代路径是单电梯->多电 ...

  9. qt解决release后数据库连接不上的问题

    问题 : 明明已经设置了 "./xxx" , 为什么release之后数据库还是连不上呢 解决 : 项目中建立一个plugins文件夹 将qt安装目录下的sqldrivers复制到 ...

  10. 税务ukey如何批量开票

    最近税局开始大力推税务ukey版本,不过目前接口还未开放,就连航信,百旺否还没有对应接口,所以自己研究了下,在之前税控基础上,谁知道搞定了,通过安装插件可以批量开票,包括纸质,电子发票ofd格式. 联 ...