CF1768F Wonderful Jump 题解

news/发布时间2024/5/20 5:20:57

考虑 dp,记 \(f_i\) 表示跳到位置 \(i\) 的最小代价,考虑哪些状态会对当前状态有贡献。

考虑状态 \(f_j\) 对当前状态有贡献需要满足什么条件,发现如果存在 \(j<k<i\) 满足 \(a_k=\min(a_j,a_{j+1},\dots,a_i)\),则先跳到 \(k\) 再跳到 \(i\) 会更优。可得 \(\min(a_j,a_{j+1},\dots,a_i)\in\{a_j,a_i\}\)

考虑对 \(i-j\) 进行根号分治,当 \(i-j\le \sqrt n\) 时,直接暴力更新即可。当 \(i-j>\sqrt n\) 时,因为代价不会超过 \(n(i-j)\)(每次跳一个),所以 \(\min(a_j,a_{j+1},\dots,a_i)<\sqrt n\)

\(\min(a_j,a_{j+1},\dots,a_i)=a_j/a_i\) 两种情况考虑即可。对于等于 \(a_i\) 的情况,发现 \(a_i<\sqrt n\),直接暴力枚举。对于等于 \(a_j\) 的情况,初始 \(j\) 为左边第一个满足 \(a_j\le a_i\) 的位置,每次跳到左边第一个小于当前 \(a_j\) 的位置更新即可。

时间复杂度 \(\mathcal O(n\sqrt n)\)

参考代码:

#include<bits/stdc++.h>
#define ll long long
#define mxn 400003
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define rept(i,a,b) for(int i=a;i<b;++i)
#define drep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
int n,t,ls,q[mxn],a[mxn],l1[mxn],l2[mxn],l3[mxn];
ll dp[mxn];
signed main(){scanf("%d",&n);const int b=sqrt(n);rep(i,1,n)scanf("%d",&a[i]);rep(i,1,n){while(t&&a[q[t]]>a[i])t--;l1[i]=q[t];q[++t]=i;}t=0;rep(i,1,n){while(t&&a[q[t]]>=a[i])t--;l2[i]=q[t];q[++t]=i;}rep(i,1,n){if(a[i]<=b)ls=i;l3[i]=ls;}rep(i,2,n){dp[i]=n*(i-1ll);int mn=a[i];drep(j,i-1,max(1,i-b)){mn=min(mn,a[j]);dp[i]=min(dp[i],dp[j]+(ll)(i-j)*(i-j)*mn);}int k=l3[l1[i]];if(a[i]<=b){drep(j,i-1,1){if(a[j]<=a[i])break;dp[i]=min(dp[i],dp[j]+(ll)(i-j)*(i-j)*a[i]);}}while(k){dp[i]=min(dp[i],dp[k]+(ll)(i-k)*(i-k)*a[k]);k=l2[k];}}rep(i,1,n)cout<<dp[i]<<' ';return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/12627503.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

[转帖]Oracle Linux 9.3 正式版发布 - Oracle 提供支持 RHEL 兼容发行版

sysin2023-11-21 上海 阅读 5 分钟 Oracle Linux 9.3 正式版发布 - Oracle 提供支持 RHEL 兼容发行版 Oracle Linux with Unbreakable Enterprise Kernel (UEK) & Red Hat compatible kernel (RHCK) 请访问原文链接:https://sysin.org/blog/oracle-linux-9/,查看最新版。…

OpenVX技术图例(一)

OpenVX技术图例(一) 参考文献链接 https://registry.khronos.org/OpenVX/specs/1.1/html/index.html人工智能芯片与自动驾驶

C++ 数据输入cin (解决CLoin输入中文程序出错)

数据输入cin语法:cin >> 变量 解决 CLoin 使用cin输入中文程序无法正常运行按住Ctrl+alt+shift+/键 弹出对话框选择注册表取消勾选run.process.with.pty

C++数据类型

整型C++除了int类型 还有其他类型的数据,所占空间也不一样 sizeof() 函数——得到数据所占的字节#include "iostream" using namespace std;int main() {system("chcp 65001");long long num = 20;cout << "long long 类型占" << s…

C++ cout打印输出 (解决输出乱码)

cout打印输出输出单份内容// 输出单份内容cout << "Hello World!" << endl;cout << 10 << endl;输出多份内容// 输出多份内容cout << "I am " << 18 << "years old" << endl;可以自由组合多个&…

三角函数之和差化积公式

知识点1:三角函数奇偶性: \(\sin(-\theta)=-\sin\theta, \quad \cos(-\theta)=\cos\theta\)如上图: 单位半圆的半径为1,\(\triangle AOB\)为等腰三角形。 点\(C\)为线段\(AB\)之中点,连接\(CO\)。 根据等腰三角形的性质,\(OC\) 是 \(△AOB\) 的角平分线和垂直平分线。 \(…