原文链接http://www.cnblogs.com/zhouzhendong/p/9004583.html

题目传送门 - Codechef CHSIGN

题意

  第一行,一个数$T$,表示数据组数。

  对于每一组数据,给定一个$n$,接下来是一个长度为$n$的数列$a$,$a$的第$i$项为$a_i$。

  所有$a_i$都是正整数。现在你可以选择若干个不同的$a_i$使他取相反数,但是你需要保证修改后的序列的任意一段长度大于$1$的连续自序列的数字总和都为正数。在满足条件的基础上,最小化修改之后$\sum_{i=1}^n a_i$,并输出方案。

  $T,n\leq 10^5,\ \sum n \leq 5\times 10^5,\ a_i\leq 10^9$

题解

  对操作之后的序列求前缀和之后,我们可以得出以下结论:

  $s_i>s_{i-2}\ \ \ \ (i=2)$

  $s_i>s_{i-2}且s_i>s_{i-3}\ \ \ (2<i\leq n)$

  而且,显然,被修改的$a_i$必然满足$a_i>a_{i-1},\ a_i>a_{i+1}$(当$i=1或i=n$的时候稍微特殊)。

  设$dp_i$为处理了$a_{1\cdots i}$且修改了$a_i$时,保证前$i$个元素构成的子序列合法,$\sum a_{1\cdots i}$的最大值。

  先不考虑转移条件,列出转移方程:

$$dp_i=\min(dp_j-s_j+s_i-2a_i)$$(这里的$s$指$a$被修改之前的$s$,不要和之前提到的$s$混淆,后面的也要注意。)

  然后我们来罗列一下条件:

  对于$i$,满足$a_i>a_{i-1},\ a_i>a_{i+1}$。

  于是第$i-1$个元素不能被修改,故$j<i-1$。

  当$j=i-2$时,需要满足$-a_{i-2}+a_{i-1}-a{i}>0$。

  当$j<i-2$时,由于$a_i>a_{i-1},\ a_i>a_{i+1}$,所以$s_{i}>s_{i-2},\ s_{i}>s_{i-3}$且$s_{i+1}>s_{i-1},\ s_{i+1}>s_{i-2}$(太显然了,自己验证)。所以只要$j<i-2$就可以转移。于是我们只需要对$dp_j-s_j$取个前缀$\min$即可。

  至于求方案这个没什么思维含量就不说了。

代码

#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,显然可以
*/

  

Codechef CHSIGN Change the Signs(May Challenge 2018) 动态规划的更多相关文章

  1. Codechef October Challenge 2018 游记

    Codechef October Challenge 2018 游记 CHSERVE - Chef and Serves 题目大意: 乒乓球比赛中,双方每累计得两分就会交换一次发球权. 不过,大厨和小 ...

  2. Codechef September Challenge 2018 游记

    Codechef September Challenge 2018 游记 Magician versus Chef 题目大意: 有一排\(n(n\le10^5)\)个格子,一开始硬币在第\(x\)个格 ...

  3. Codeforces Avito Code Challenge 2018 D. Bookshelves

    Codeforces Avito Code Challenge 2018 D. Bookshelves 题目连接: http://codeforces.com/contest/981/problem/ ...

  4. Lyft Level 5 Challenge 2018 - Final Round (Open Div. 2) (前三题题解)

    这场比赛好毒瘤哇,看第四题好像是中国人出的,怕不是dllxl出的. 第四道什么鬼,互动题不说,花了四十五分钟看懂题目,都想砸电脑了.然后发现不会,互动题从来没做过. 不过这次新号上蓝名了(我才不告诉你 ...

  5. codechef February Challenge 2018 简要题解

    比赛链接:https://www.codechef.com/FEB18,题面和提交记录是公开的,这里就不再贴了 Chef And His Characters 模拟题 Chef And The Pat ...

  6. Codechef STMINCUT S-T Mincut (CodeChef May Challenge 2018) kruskal

    原文链接http://www.cnblogs.com/zhouzhendong/p/9010945.html 题目传送门 - Codechef STMINCUT 题意 在一个有边权的无向图中,我们定义 ...

  7. Codechef August Challenge 2018 : Chef at the River

    传送门 (要是没有tjm(Sakits)的帮忙,我还真不知道啥时候能做出来 结论是第一次带走尽可能少的动物,使未带走的动物不冲突,带走的这个数量就是最优解. 首先这个数量肯定是下界,更少的话连第一次都 ...

  8. Codechef August Challenge 2018 : Safe Partition

    传送门 (虽然是A了但是不知道复杂度是不是正确的 考虑以某个位置为结尾的合法划分 先考虑min,带来的影响是限制了最小长度,预处理出这个最小长度后,这可以在处理到这个数时,把不能算的部分去掉(不满足m ...

  9. Codechef August Challenge 2018 : Interactive Matrix

    传送门 首先整个矩阵可以被分为很多小矩阵,小矩阵内所有行的单调性是一样的,所有列的单调性是一样的. 考虑如何在这样一个小矩阵中找出答案.我的策略是每次取四个角中最大值和最小值的点,这样可以每次删掉一行 ...

随机推荐

  1. chrome:禁用缓存

    F12->Network 非常好用!!!!!!!!!!

  2. Linux多台主机间配置SSH免密登陆

    1.安装ssh.  sudo apt-get install ssh. 安装完成后会在~目录(当前用户主目录,即这里的/home/xuhui)下产生一个隐藏文件夹.ssh(ls -a 可以查看隐藏文件 ...

  3. Jmeter之csv参数化

    创建数据源csv文件 在线程组中添加CSV Data Set Config 1.添加CSV Data Set Config 添加CSV Data Set Config 2.配置CSV Data Set ...

  4. Metrics介绍和Spring的集成

    参考: http://colobu.com/2014/08/08/Metrics-and-Spring-Integration/ https://www.cnblogs.com/yangecnu/p/ ...

  5. centos6.5 有趣但是没有用的linux命令

    小火车 get http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm rpm -ivh epel-rele ...

  6. JavaWEB后端支付银联,支付宝,微信对接

    注:本文来源于:<  JavaWEB后端支付银联,支付宝,微信对接  > JavaWEB后端支付银联,支付宝,微信对接 标签(空格分隔): java 项目概述 最近项目需要后端打通支付,所 ...

  7. Confluence 6 从一个 XML 备份中导入一个空间

    有下面 2 中方法可以导入一个空间——通过上传一个文件,或者从你 Confluence 服务器上的一个目录中导入.上传文件仅仅是针对一个小站点的情况.为了取得最好的导入结果,我们推荐你从服务器上的目录 ...

  8. Remove Duplicates from Sorted ListII

    给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字. 示例 1: 输入: 1->2->3->3->4->4->5 输出: 1-&g ...

  9. LeetCode(98): 验证二叉搜索树

    Medium! 题目描述: 给定一个二叉树,判断其是否是一个有效的二叉搜索树. 一个二叉搜索树具有如下特征: 节点的左子树只包含小于当前节点的数. 节点的右子树只包含大于当前节点的数. 所有左子树和右 ...

  10. lightoj 1220 唯一分解定理

    #include<bits/stdc++.h> using namespace std; #define maxn 1000005 #define ll long long int v[m ...