[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. sublime配置C++编译环境

    配置C++编译命令 { "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$", "workin ...

  2. ubuntu安装qt步骤(源码)

    1.安装gcc,g++ sudo apt-get install gcc sudo apt-get install g++ 2.解压源码包 tar xvzf qt-xxxx 3.安装xlib库 sud ...

  3. SQL--SQL详解(DDL,DML,DQL,DCL)

    SQL--SQL详解(DDL,DML,DQL,DCL) 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 什么是SQL? Stru ...

  4. @bzoj - 1921@ [ctsc2010]珠宝商

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 简述版题意:给定字符串 S 与一棵树 T,树上每个点有一个字符. ...

  5. (六)TestNg中的软断言和硬断言

    原文链接:https://cloud.tencent.com/developer/article/1479172 前言 在执行自动化测试脚本的时候,我们需要自动判断测试脚本执行完成后的实际结果是否与预 ...

  6. post请求头的常见类型

    1.application/json(JSON数据格式) xhr.setRequestHeader("Content-type","application/json; c ...

  7. Scrapy学习1:安装

    Install Scrapy 熟悉PyPI的话,直接一句 pip install Scrapy 但是有时候需要处理安装依赖,不能直接一句命令就安装结束,这个和系统有关. 我用的Ubuntu,这里仅介绍 ...

  8. Docker精华 ,超全文档!

    我们的口号是:再小的帆也能远航,人生不设限!!    学习规划:继续上篇 <Docker入门>https://www.cnblogs.com/dk1024/p/13121389.html  ...

  9. 虚拟机VMware克隆之后网络不可用的解决办法

    现在有两台虚拟机,113是111的克隆,要让113能够使用,需要做下面的修改 5.解决办法5.1.修改克隆后机器(B机器)70-persistent-net.rules文件内容 对克隆后机器(B机器) ...

  10. android 中IntentService的使用场景

    IntentService是继承并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统的Service一样,同时,当任务执行 ...