AT_agc040_e [AGC040E] Prefix Suffix Addition 题解
比较巧的题。
先考虑只有 \(1\) 操作时怎么做,显然答案为满足 \(1\le i<n\land A_i>A_{i+1}\) 的 \(i\) 的个数,即每次选一段尽量长的不降段进行操作。
接下来加上 \(2\) 操作,考虑对每个 \(i\) 将 \(A_i\) 分为 \(x_i\) 和 \(A_i-x_i\),\(x_i\) 用 \(1\) 操作,\(A_i-x_i\) 用 \(2\) 操作,答案即为 \(\sum_{i=2}^n [x_i<x_{i-1}]+[A_i-x_i>A_{i-1}-x_{i-1}]\),即 \(\sum_{i=2}^n [x_i<x_{i-1}]+[x_i<x_{i-1}+A_i-A_{i-1}]\)。容易得到一个比较暴力的 dp:记 \(f_{i,j}\) 表示确定 \(x_1,x_2,\dots,x_i\),\(x_i\) 为 \(j\) 的最少代价,有:
\[f_{i,j}=\min_{k=0}^{A_{i-1}}\{f_{i-1,k}+[j<k]+[j<k+A_i-A_{i-1}]\}
\]
发现 \([j<k]+[j<k+A_i-A_{i-1}]\) 总共有三种值,对每个 \(i\) 把 \(f_{i,j}\) 分成了三段,记录前两段的右端点直接转移即可,时间复杂度 \(\mathcal O(n)\)。
参考代码:
#include<bits/stdc++.h>
#define ll long long
#define mxn 200003
#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,ans,a[mxn],f[mxn][2];
signed main(){
scanf("%d",&n);
rep(i,1,n)scanf("%d",&a[i]);
rep(i,1,n){
if(a[i]>=a[i-1]){
f[i][0]=f[i-1][0];
f[i][1]=max(f[i-1][1],f[i-1][0]+a[i]-a[i-1]);
}else{
f[i][0]=f[i-1][0]+a[i]-a[i-1];
f[i][1]=max(f[i-1][0],f[i-1][1]+a[i]-a[i-1]);
if(f[i][0]<0){
ans++;
f[i][0]=f[i][1],f[i][1]=a[i];
}
}
f[i][0]=min(f[i][0],a[i]);
f[i][1]=min(f[i][1],a[i]);
}
cout<<ans+(f[n][0]<a[n]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2024-02-28 联合省选 2024 游记
2024-02-28 [USACO13MAR]Farm Painting S 题解
2024-02-28 CF111D Petya and Coloring 题解
2024-02-28 CF1034E Little C Loves 3 III 题解
2024-02-28 P2065 [TJOI2011] 卡片 题解
2024-02-28 CF756D Bacterial Melee 题解