CF855B Marvolo Gaunt‘s Ring题解
传送门
题意
给 nnn 个数,按顺序取三个 ai,aj,aka_i,a_j,a_kai,aj,ak ,使
p×ai+q×aj+r×akp×a_i+q×a_j+r×a_kp×ai+q×aj+r×ak 最大。
注意 1≤i≤j≤k≤n1≤i≤j≤k≤n1≤i≤j≤k≤n 。
O(n3)O(n^3)O(n3) 暴力解法
for循环枚举 ai,aj,aka_i,a_j,a_kai,aj,ak ,取 maxmaxmax 。
或者是枚举 ai,aja_i,a_jai,aj ,最后的 aka_kak 取 [j,n][j,n][j,n] 的最值,
如果 r>0r>0r>0 , aka_kak 取最大值;
反之, aka_kak 取最小值。
这样显然会TLE的。
O(nlogn)O(n\log n)O(nlogn) 解法
在看看上面枚举两个数的算法,再想想可以只枚举一个数吗?
诶,好像可以诶!
我们枚举中间的 aja_jaj ,那么 aia_iai 就是 [1,j][1,j][1,j] 的最值, aka_kak 是 [j,n][j,n][j,n] 的最值。然后用ST算法或线段树,维护区间最值。(不会?戳这儿->ST算法)
话不多说,上代码!
这里用的是ST算法,可以通过 O(nlogn)O(n\log n)O(nlogn) 的时间复杂度作预处理后,在 O(1)O(1)O(1) 的复杂度内查询区间最值。
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
using namespace std;typedef long long ll;const int N=100005;
const ll INF=9e18;int n;
ll p,q,r;
ll a[N];
ll f[N][20][2]; //f[i][j][0]表示在子区间[i,i + 2^j - 1]的区间最大值,f[i][j][1]位最小值
int Log[N];
ll ans=-9e18;void ST_prework()
{for(int i=1;(1<<i)<=n;i++) Log[1<<i]=i; //预处理log2(x)的值,方便查找for(int i=1;i<=n;i++) if(!Log[i]) Log[i]=Log[i-1];int t=Log[n]+1;for(int i=1;i<=n;i++) //初始化for(int j=1;j<=t;j++){f[i][j][0]=-INF;f[i][j][1]=INF;}for(int i=1;i<=n;i++) f[i][0][0]=f[i][0][1]=a[i]; //赋初值for(int j=1;j<t;j++)for(int i=1;i<=n-(1<<j)+1;i++){f[i][j][0]=max(f[i][j-1][0],f[i+(1<<(j-1))][j-1][0]);f[i][j][1]=min(f[i][j-1][1],f[i+(1<<(j-1))][j-1][1]); }
}long long ST_query(int l,int r,bool flag) //flag用于判断p/q/r大于0还是小于等于0
{int k=Log[r-l+1];if(flag) return max(f[l][k][0],f[r-(1<<k)+1][k][0]);return min(f[l][k][1],f[r-(1<<k)+1][k][1]);
}int main()
{scanf("%d%lld%lld%lld",&n,&p,&q,&r);for(int i=1;i<=n;i++) scanf("%lld",&a[i]);ST_prework();for(int i=1;i<=n;i++)ans=max(ans,q*a[i]+p*ST_query(1,i,p>0)+r*ST_query(i,n,r>0)); //取最大值printf("%lld\n",ans);return 0;
}
O(n)O(n)O(n) 算法
此时,我们换一种枚举思路,枚举到一个数 axa_xax ,分别考虑:
当枚举到第 xxx 个数时,
- 当 axa_xax 为 aia_iai 时, p×aip×a_ip×ai 的最大值
- 当 axa_xax 为 aja_jaj 时, p×ai+q×ajp×a_i+q×a_jp×ai+q×aj 的最大值
- 当 axa_xax 为 aka_kak 时, p×ai+q×aj+r×akp×a_i+q×a_j+r×a_kp×ai+q×aj+r×ak 的最大值
考虑 dpdpdp ,设 dp[i][0/1/2]dp[i][0/1/2]dp[i][0/1/2] 表示枚举到第 iii 个数时,对应的三种情况的最大值,则发现,求出第一种情况的最大值时,再加上 q×axq×a_xq×ax 可以得到第二种情况的最大值,同理可以推出第三种情况的最大值,即:
dp[i][0]=max(dp[i−1][0],p×ai)dp[i][0]=max(dp[i-1][0],p×a_i)dp[i][0]=max(dp[i−1][0],p×ai)
dp[i][1]=max(dp[i−1][1],dp[i][0]+q×ai)dp[i][1]=max(dp[i-1][1],dp[i][0]+q×a_i)dp[i][1]=max(dp[i−1][1],dp[i][0]+q×ai)
dp[i][2]=max(dp[i−1][2],dp[i][1]+r×ai)dp[i][2]=max(dp[i-1][2],dp[i][1]+r×a_i)dp[i][2]=max(dp[i−1][2],dp[i][1]+r×ai)
由于iii是递增的,所以存的最大值中取的 i,j,ki,j,ki,j,k 一定满足 i≤j≤ki≤j≤ki≤j≤k ,
所以最后答案为 dp[n][2]dp[n][2]dp[n][2] 。
再观察,发现 dp[i]dp[i]dp[i] 只与 dp[i−1]dp[i-1]dp[i−1] 的值有关,所以直接压掉第一维,答案为 dp[2]dp[2]dp[2] 。
时间复杂度为 O(n)O(n)O(n) ,空间复杂度 O(1)O(1)O(1) 。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;typedef long long ll;const ll INF=9e18;int n;
int p,q,r;
ll dp[3];int main()
{scanf("%d%d%d%d",&n,&p,&q,&r);dp[0]=dp[1]=dp[2]=-INF;for(int i=1;i<=n;i++){int x;scanf("%d",&x);dp[0]=max(dp[0],(ll)x*p); //按顺序依次状态转移dp[1]=max(dp[1],dp[0]+(ll)x*q);dp[2]=max(dp[2],dp[1]+(ll)x*r);}printf("%lld\n",dp[2]);return 0;
}
CF855B Marvolo Gaunt‘s Ring题解相关推荐
- B. Marvolo Gaunt’s Ring (递推)
B. Marvolo Gaunt's Ring 题目链接 大致题意: 给你三个数 p,q,r,然后给你给你一个有序的序列,让你在序列中跳出三个数i,j,k(i <=j<=k)使得 p*a[ ...
- Marvolo Gaunt's Ring 【CodeForces 855B】
Marvolo Gaunt's Ring 求p * i + q * j + r * k(i<=j<=k)的最大值 虽然题中给的时间比较长但还是不可以用直接暴力用三次for循环,一定可以用一 ...
- Marvolo Gaunt's Ring(类似于dp的做法)
题目:(题目传送门) Professor Dumbledore is helping Harry destroy the Horcruxes. He went to Gaunt Shack as he ...
- Marvolo Gaunt's Ring ---CodeForces - 855B(思维题)
题目链接:http://codeforces.com/problemset/problem/855/B Marvolo Gaunt's Ring Professor Dumbledore is hel ...
- Codeforces 855B - Marvolo Gaunt's Ring
855B - Marvolo Gaunt's Ring 思路:①枚举a[j],a[i]和a[k]分别用前缀最小值最大值和后缀最小值和后缀最大值确定. ②dp,dp[i][j]表示到第j为止,前i+1个 ...
- Marvolo Gaunt's Ring CodeForces - 855B+线段树+维护区间最大值和最小值
题目链接: Marvolo Gaunt's Ring CodeForces - 855B 题目大意: 给定一段序列:a1,a2,a3,--an, 给定三个数:p,q,r(注意数据范围,代码里ans=- ...
- 【ST】【CF855B】 Marvolo Gaunt's Ring
传送门 Description 给定三个数 \(p~,~q~,~r~\),以及一个数组 \(a\), 找出三个数 \(i~,~j~,~k\) ,其中 \(i~\leq~j~\leq~k\) 最大化 \ ...
- codeforces 855-B. Marvolo Gaunt's Ring
http://codeforces.com/problemset/problem/855/B 这个题一开始读错了没想到要按顺序之后看到这个就像枚举但是数据太大...emmm然后就有点蒙. 后来看了题解 ...
- CodeForces - 855B - Marvolo Gaunt's Ring(线段树 or DP)
题目:CodeForces - 855B 题解: 1.用dp做的: dp[0][i]是前i个p*a[i]的最大值, dp[1][i]是在dp[0][i]的基础上加上q*a[i]的最大值,这样可以保证j ...
最新文章
- 程序员的岗位方向和所需技能都有哪些?
- 玩玩TCPCOPY+ intercept+mysql-replay-module(未成功)
- 这个需求很简单,明天上线没问题吧?要不要怼回去?
- extjs 限制上传文件类型_如何让extjg 支持选择多文件上传
- 重学java基础第十一课:基本的dos命令
- 443显示正常服务器错误,wordpress 出现443 NOT FOUND-apache错误的解决方案
- 通过可视化来了解你的Spark应用程序
- 互联网金融盯上房地产资金饥渴症
- Windows下搭建elasticsearch集群案例
- [问题解决]win10误删启动项(BCD)(HP电脑亲测,无需启动盘,并非重装系统)
- 拓端tecdat|R语言:结构方程模型、潜变量分析
- 社会工程学之《反欺骗的艺术》的思考
- C++ Primer Plus 第六版课后习题答案(第五章)
- 华为手机海拔测试软件,华为手机海拔高度测量仪
- matlab直方图均衡化实现
- xp如何在电脑上设置无线网络连接服务器,xp电脑怎么设置wifi
- 09|自研or借力(下):集成Gin替换已有核心
- 拓展半导体材料和零件领域 SK集团布局解读
- 服务器的系统日志路径,DirectAdmin 日志路径各种系统中查看方法Windows服务器操作系统 -电脑资料...
- 机器学习-吃瓜教程(西瓜书+南瓜书)-神经网络