隐藏页面特效

[262144 P]

1|0262144 P


1|1题目描述


游戏一开始有n个正整数,(2<=n<=262144),范围在140。在一步中,贝西可以选相邻的两个相同的数,然后合并成一个比原来的大一的数(例如两个7合并成一个8),目标是使得最大的数最大,请帮助Bessie来求最大值

1|2思路


我们假设所有的数全是40那么最大可以合成出来的数是58,可作为数组的一维

定义f[i][j]为能合成出来i,且左端点为j的情况下的区间长度/右端点,右端点比区间长度稍简单一点,这里采用右端点的情况

状态转移方程:f[i][j]=f[i1][f[i1][j]]

这里有类似倍增的意思,f[i1][j]是以j为左端点,能合成出i1的右端点,那f[i1][f[i1][j]]就是以上一个右端点作为下一次左端点再往后找,那么就是两个i1合成了i

1|3初始化/区间开闭问题


f[a[i]][i]]=i+1,这里要定义为左闭右开的区间

举个例子如果是两个1要合成2,那么f[2][1]=f[1][f[1][1]]如果不加1的话,它更新完就还是1没法扩展过去,更离谱的是:如果不加1,且一共只有一个数的情况下,它甚至可以自己左脚踩右脚一直往上增,所有的f[n][1]都会被更新,考虑完上面的情况就可以直接给出代码

洛谷P3147

#include <cstdio> #include <iostream> using namespace std; const int maxn = 262145; int ans,n,f[60][maxn];//f(i,j)表示能合成i,左端点为j情况下的右端点(左闭右开区间) int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); f[x][i] = i + 1; } for(int i=1;i<=58;i++) { for(int j=1;j<=n;j++) { if(!f[i][j]) f[i][j] = f[i-1][f[i-1][j]]; if(f[i][j]) ans = i; } } printf("%d",ans); return 0; }

__EOF__

本文作者风丨铃
本文链接https://www.cnblogs.com/-Wind-/p/18072494.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   风丨铃  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
历史上的今天:
2019-03-14 [状压DP]
点击右上角即可分享
微信分享提示