Codeforces 1077(F1+F2) DP 单调队列
题意:给你一个n个元素的数组,从中选取x个元素,并且要保证任意的m个位置中必须至少有一个元素被选中,问选中元素的和最大可以是多少?
F1 n,m,x到200 F2 n,m,x到5000。
思路1:设dp[i][j]为选择i位置的元素,并且包括i位置已经选择了j个元素,所有选中元素的最大和。
那么为了保证方案的合法性,只能从i-m+1的地方状态转移,dp[i][j]=max(dp[k][j-1])+a[i] (i-m+1<=k<i);,意思是找从i-m+1位置到i-1位置找已经选区j-1个元素中和最大的一个,在加上自己。
最后在n-m+1到i中找最大值就是答案,这些点因为已经被选取,所以保证了最终答案的合法性。
代码:
#include<bits/stdc++.h>
using namespace std;
long long dp[210][210],a[210];
int main(){
int n,m,x;
scanf("%d%d%d",&n,&m,&x);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
int tmp=n-(m-1);
if((tmp/m+(tmp%m!=0))>x){
printf("-1\n");
return 0;
}
int lim=1;
for(int i=1;i<=n;i++){
for(int j=lim;j<=min(i,x);j++){
for(int k=max(0,i-m);k<i;k++){
dp[i][j]=max(dp[k][j-1]+a[i],dp[i][j]);
}
}
if(i%m==0)lim++;
} long long ans=0;
for(int i=n-m+1;i<=n;i++)
ans=max(ans,dp[i][x]);
printf("%lld\n",ans);
}
思路2:现在数据规模变大了,原来的做法可以卡成O(n3),过不了。仔细观察状态转移过程,会发现有很多无用的状态,比如dp[i][j-1]<dp[k][j-1] (i<k),dp[i][j-1]这个状态肯定不会成为更新的跳板,于是我们就可以用单调队列优化。
外层循环枚举选取的元素个数,内层循环枚举数组的元素,用单调队列的队头更新最优解,此时dp[i][j]表示已经选区了i个元素,第j个元素已经被选的最优解,单调队列的队头出队过程保证了方案的合法性。
代码:
#include<bits/stdc++.h>
using namespace std;
long long dp[2][5010],a[5010];
int q[100010],l=1,r=0;
int main(){
int n,m,x;
scanf("%d%d%d",&n,&m,&x);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
int tmp=n-(m-1);
if((tmp/m+(tmp%m!=0))>x){
printf("-1\n");
return 0;
}
memset(dp,-0x3f,sizeof(dp));
dp[1][0]=0;
int now=0;
for(int i=1;i<=x;i++){
l=1,r=0;
q[++r]=0;
for(int j=1;j<=n;j++){
while(l<=r&&q[l]+m<j)l++;
dp[now][j]=dp[now^1][q[l]]+a[j];
while(l<=r&&dp[now^1][q[r]]<=dp[now^1][j])r--;
q[++r]=j;
}
now^=1;
}
now^=1;
long long ans=-1;
for(int i=n-m+1;i<=n;i++)
ans=max(ans,dp[now][i]);
printf("%lld\n",ans);
}
---恢复内容结束---
Codeforces 1077(F1+F2) DP 单调队列的更多相关文章
- Codeforces 445A Boredom(DP+单调队列优化)
题目链接:http://codeforces.com/problemset/problem/455/A 题目大意:有n个数,每次可以选择删除一个值为x的数,然后值为x-1,x+1的数也都会被删除,你可 ...
- [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)
DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...
- DP+单调队列 codevs 1748 瑰丽华尔兹(还不是很懂具体的代码实现)
codevs 1748 瑰丽华尔兹 2005年NOI全国竞赛 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 Descripti ...
- 习题:烽火传递(DP+单调队列)
烽火传递[题目描述]烽火台又称烽燧,是重要的防御设施,一般建在险要处或交通要道上.一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息:夜晚燃烧干柴,以火光传递军情.在某两座城市之间有n个烽火台,每个烽火台 ...
- (noip模拟二十一)【BZOJ2500】幸福的道路-树形DP+单调队列
Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...
- 3622 假期(DP+单调队列优化)
3622 假期 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 黄金 Gold 题目描述 Description 经过几个月辛勤的工作,FJ决定让奶牛放假.假期可以在1-N天内任意选择 ...
- Codeforces 1077F2 Pictures with Kittens (hard version)(DP+单调队列优化)
题目链接:Pictures with Kittens (hard version) 题意:给定n长度的数字序列ai,求从中选出x个满足任意k长度区间都至少有一个被选到的最大和. 题解:数据量5000, ...
- Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列
原文链接https://www.cnblogs.com/zhouzhendong/p/CF980F.html 题目传送门 - CF980F 题意 给定一个 $n$ 个节点 $m$ 条长为 $1$ 的边 ...
- 【简洁易懂】CF372C Watching Fireworks is Fun dp + 单调队列优化 dp优化 ACM codeforces
题目大意 一条街道有$n$个区域. 从左到右编号为$1$到$n$. 相邻区域之间的距离为$1$. 在节日期间,有$m$次烟花要燃放. 第$i$次烟花燃放区域为$a_i$ ,幸福属性为$b_i$,时间为 ...
随机推荐
- c#将DataTable内容导出为CSV文件
写了个类: class DataTableAndCSV { public static DataTable csvToDataTable(string file) { string strConn = ...
- 小米刷机教程和GAE for android
小米上的刷机教程:http://www.miui.com/getrom.php?r=2gae for android :https://github.com/madeye/gaeproxy/wiki
- JAX-RS介绍——Java API forRESTful WebServices,JAX-RS的目标是Web Services开发(这与HTML Web应用不同)而Spring MVC的目标则是Web应用开发
JAX-RS Java API forRESTful WebServices旨在定义一个统一的规范,使得 Java 程序员可以使用一套固定的接口来开发 REST 应用,避免了依赖于第三方框架.是一个J ...
- Linux下tar命令的各种参数选项和他们的作用整理
1.建立TAR包(打包)命令格式:tar cvf TAR包文件名.tar 所备份的文件或目录功能描述:tar cvf命令用于把指定的目录或文件打包到指定的文件中.“c”指定建立(或压缩)TAR包,“v ...
- [独孤九剑]Oracle知识点梳理(十)%type与%rowtype及常用函数
本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...
- mysql 多表查询 左联 去重方法
1.数据库中的两张表: 2.传统左联查询数据结果如下: 3.替换查询语句可得到去重数据结果:
- jQuery中 :first、:first-child 和 :first-of-type 之间的不同
<!DOCTYPE html><html><head><meta charset="utf-8"><script src=&q ...
- FPGA中竞争冒险问题的研究
什么是竞争冒险? 1 引言 现场可编程门阵列(FPGA)在结构上由逻辑功能块排列为阵列,并由可编程的内部连线连接这些功能块,来实现一定的逻辑功能. FPGA可以替代其他PLD或者各种中小规模数 ...
- [转载]python的range()函数用法
使用python的人都知道range()函数很方便,今天再用到他的时候发现了很多以前看到过但是忘记的细节.这里记录一下range(),复习下list的slide,最后分析一个好玩儿的冒泡程序. 这里记 ...
- shell脚本 - 快速到达目录
服务器中存放很多工程目录,通过ssh登录,需要手动敲命令,很麻烦,可以建立自动登录脚本 1.在服务器登录是默认的目录中建立脚本文件 vi drivers.sh #建立登录脚本 cd data/work ...