【CF933E】A Preponderant Reunion(动态规划)
【CF933E】A Preponderant Reunion(动态规划)
题面
题解
直接做很不好搞,我们把条件放宽,我们每次可以选择两个相邻的非零数让他们减少任意值,甚至可以减成负数(虽然你肯定不会把它弄成负数的)。代价为减少的值。不难证明这个问题的答案不会优于原题目。
我们假定只处理\([l,r]\)这段区间的数\(p_l,p_{l+1},...,p_r\)的答案,为了方便,我们假定数列开头结尾都是\(0\)。
我们令\(c_l=p_l,c_i=\max\{p_i-c_{i-1},0\}\),那么我们必定可以构造一种方案,使得处理这一段区间使得所有数都变成非负数的代价为\(\sum c_i\)。然后设\(f[l][r]\)为这个值。
f[l][r]&=f[l][r-2]+c_{r-1}+c_r\\
&=f[l][r-2]+c_{r-1}+\max\{p_r-c_{r-1},0\}\\
&=f[l][r-2]+\max\{p_r,c_{r-1}\}\\
&\ge f[l][r-2]+p_r\\
&=f[l][r-2]+f[r][r]
\end{aligned}\]
所以一个区间\([l,r]\)可以拆分成\([l,r-2]\)这个区间的打啊,然后是\(r-1\)保留为正数,\([r,r]\)这个区间的答案。然后递归处理前面这一段区间,我们得到的就是每次可以拆分出\(2\)个或者\(1\)个位置使得他们变成\(0\),有\(2\)的原因是当区间长度为\(2\)的时候不得不使得两个位置都是\(0\)而不能拆分。
于是我们就考虑每次放\(0\)段的长度,这个长度可以是\(1\)或者\(2\),然后大力转移一下就可以。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 300300
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,p[MAX],g[MAX];ll f[MAX];
vector<int> Ans;
void Work(int i){int x=min(p[i],p[i+1]);if(!x)return;Ans.push_back(i);p[i]-=x;p[i+1]-=x;}
int main()
{
n=read();
for(int i=1;i<=n;++i)p[i]=read();
memset(f,63,sizeof(f));f[0]=0;
for(int i=1;i<=n;++i)
{
f[i]=min(f[max(i-2,0)]+p[i],f[max(i-3,0)]+max(p[i],p[i-1]));
if(f[i]==f[max(i-3,0)]+max(p[i],p[i-1]))g[i]=1;
}
ll ans=min(f[n],f[n-1]);
for(int i=n-(ans==f[n-1]);i>0;i=i-2-g[i])
{
Work(i-1);if(g[i])Work(i-2);Work(i);
}
printf("%d\n",(int)Ans.size());
for(int v:Ans)printf("%d\n",v);
return 0;
}
【CF933E】A Preponderant Reunion(动态规划)的更多相关文章
- CF933E A Preponderant Reunion DP
传送门 题解搬运工 设原问题为问题A.每一次减少\(\min\{p_i , p_{i+1}\}\)难以处理,我们考虑将限制变得宽松一些:每一次可以减少\([1,\min\{p_i , p_{i+1}\ ...
- 增强学习(三)----- MDP的动态规划解法
上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...
- 简单动态规划-LeetCode198
题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...
- 动态规划 Dynamic Programming
March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...
- 动态规划之最长公共子序列(LCS)
转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...
- C#动态规划查找两个字符串最大子串
//动态规划查找两个字符串最大子串 public static string lcs(string word1, string word2) { ...
- C#递归、动态规划计算斐波那契数列
//递归 public static long recurFib(int num) { if (num < 2) ...
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- 【BZOJ1700】[Usaco2007 Jan]Problem Solving 解题 动态规划
[BZOJ1700][Usaco2007 Jan]Problem Solving 解题 Description 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地 ...
随机推荐
- 【tf.keras】tensorflow datasets,tfds
一些最常用的数据集如 MNIST.Fashion MNIST.cifar10/100 在 tf.keras.datasets 中就能找到,但对于其它也常用的数据集如 SVHN.Caltech101,t ...
- a是什么??
//解决Linux下默认中文字体乱码问题 QFont font("simsun", 11, QFont::Normal, false); a.setFont(font);
- C语言程序设计100例之(21):折半查找
例21 折半查找 问题描述 顺序查找是一种最简单和最基本的检索方法.其基本思想是:从检索表的一端(如表中第一个记录或最后一个记录)开始,逐个进行记录的关键字和给定值的比较.若某个记录的关键字和给定值 ...
- Python实战——基于股票的金融数据量化分析
说明:本文只是通过自己的已学知识对股票数据进行了一个简单的量化分析,只考虑了收盘情况,真实的量化交易中仅仅考虑收盘情况是不够的,还有很多的复杂因素,而且仅仅三年数据是不足以来指导真实的股票交易的,因此 ...
- 对numpy.meshgrid()理解
一句话解释numpy.meshgrid()——生成网格点坐标矩阵.关键词:网格点,坐标矩阵 网格点是什么?坐标矩阵又是什么鬼?看个图就明白了: 图中,每个交叉点都是网格点,描述这些网格点的坐标的矩阵, ...
- .Net Core 3.0后台使用httpclient请求网络网页和图片_使用Core3.0做一个简单的代理服务器
目标:使用.net core最新的3.0版本,借助httpclient和本机的host域名代理,实现网络请求转发和内容获取,最终显示到目标客户端! 背景:本人在core领域是个新手,对core的使用不 ...
- 第一篇随笔:用VB.NET搞点简单事情(1)
网络上能搜索到的爬虫文章大多是用python做的,也有少部分是C#做的(小声:所以用VB.NET也可以做爬虫.本文写的是第一步:获取网页) 使用代码前先imports以下内容 Imports Syst ...
- SQL实用技巧:如何将表中某一列的部分数据合并到一行中
select *,stuff(select ‘,’ + fieldname from table1 for xml path(”)),1,1,”) as field from table2 for ...
- Mac版Sourcetree的安装使用
本人也在亲测,感觉很有效,和大家分享,参考链接: https://www.jianshu.com/p/b8d0547a8449
- 小程序登录解密用户数据encryptedData -41001: encodingAesKey 非法
问题: 做小程序微信授权登录,先获取code,然后去获取到session_key和open_id,再拿到encryptedData,传到服务器去解密拿到用户信息,但是有时成功,有时返回-41001错误 ...