Codechef CHSIGN Change the Signs(May Challenge 2018) 动态规划
原文链接http://www.cnblogs.com/zhouzhendong/p/9004583.html
题目传送门 - Codechef CHSIGN
题意
第一行,一个数T,表示数据组数。
对于每一组数据,给定一个n,接下来是一个长度为n的数列a,a的第i项为ai。
所有ai都是正整数。现在你可以选择若干个不同的ai使他取相反数,但是你需要保证修改后的序列的任意一段长度大于1的连续自序列的数字总和都为正数。在满足条件的基础上,最小化修改之后∑ni=1ai,并输出方案。
T,n≤105, ∑n≤5×105, ai≤109
题解
对操作之后的序列求前缀和之后,我们可以得出以下结论:
si>si−2 (i=2)
si>si−2且si>si−3 (2<i≤n)
而且,显然,被修改的ai必然满足ai<ai−1, ai<ai+1(当i=1或i=n的时候稍微特殊)。
设dpi为处理了a1⋯i且修改了ai时,保证前i个元素构成的子序列合法,∑a1⋯i的最大值。
先不考虑转移条件,列出转移方程:
dpi=min(dpj−sj+si−2ai)(这里的s指a被修改之前的s,不要和之前提到的s混淆,后面的也要注意。)
然后我们来罗列一下条件:
对于i,满足ai<ai−1, ai<ai+1。
于是第i−1个元素不能被修改,故j<i−1。
当j=i−2时,需要满足−ai−2+ai−1−ai>0。
当j<i−2时,由于ai<ai−1, ai<ai+1,所以si>si−2, si>si−3且si+1>si−1, si+1>si−2(太显然了,自己验证)。所以只要j<i−2就可以转移。于是我们只需要对dpj−sj取个前缀min即可。
至于求方案这个没什么思维含量就不说了。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N=100005; const LL INF=1LL<<57; int T,n; LL a[N],s[N],dp[N],f[N],Min[N]; LL cc( int i){ return dp[i]-s[i]; } int main(){ scanf ( "%d" ,&T); while (T--){ scanf ( "%d" ,&n); for ( int i=1;i<=n;i++) scanf ( "%lld" ,&a[i]),s[i]=s[i-1]+a[i]; a[n+1]=INF; LL ans=0; dp[0]=0; dp[1]=a[2]>a[1]?-a[1]:a[1]; Min[0]=0; Min[1]=cc(1)<cc(0)?1:0; for ( int i=1;i<=n;i++){ if (i>=2){ dp[i]=INF; if (a[i]<a[i-1]&&a[i]<a[i+1]){ if (-a[i-2]+a[i-1]-a[i]>0) if (dp[i-2]+s[i]-s[i-2]-2*a[i]<dp[i]){ dp[i]=dp[i-2]+s[i]-s[i-2]-2*a[i]; f[i]=i-2; } if (i-3>=0) if (cc(Min[i-3])+s[i]-2*a[i]<dp[i]){ dp[i]=cc(Min[i-3])+s[i]-2*a[i]; f[i]=Min[i-3]; } } Min[i]=cc(Min[i-1])>cc(i)?i:Min[i-1]; } if (dp[i]+s[n]-s[i]<dp[ans]+s[n]-s[ans]) ans=i; } for ( int i=ans;i;i=f[i]) a[i]=-a[i]; for ( int i=1;i<=n;i++) printf ( "%lld " ,a[i]); puts ( "" ); } return 0; } /* dp[i]=min(dp[j]+s[i]-s[j]-2*a[i]) a[i]<a[i-1],a[i]<a[i+1] j==i-2,-a[i-2]+a[i-1]-a[i]>0 j<i-2,显然可以 */ |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
· 程序员常用高效实用工具推荐,办公效率提升利器!