codeforces332B - Maximum Absurdity 线段数 or dp
题意:给你一个序列,找两个长度为 k 且没有重合区间的数使得其和最大
解题思路:
1)线段树
想了半天想不出只能先用线段树撸了一发,这题dp 第一名只要了 9分钟。
就是把起点为 i 长度为 k 的和预处理出来,再用线段树枚举去找。
解题代码:
1 // File Name: 332b.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月30日 星期三 08时10分45秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 using namespace std; 26 #define M 200004 27 struct node{ 28 int l , r ,m; 29 LL maxn,s; 30 }tree[M <<2]; 31 LL a[200004]; 32 LL sum[200004]; 33 int L(int x) 34 { 35 return 2 * x; 36 } 37 int R(int x) 38 { 39 return 2 * x + 1; 40 } 41 void pushup(int c) 42 { 43 if(tree[L(c)].maxn >=tree[R(c)].maxn) 44 { 45 tree[c].maxn = tree[L(c)].maxn; 46 tree[c].s = tree[L(c)].s; 47 }else{ 48 tree[c].maxn = tree[R(c)].maxn; 49 tree[c].s = tree[R(c)].s; 50 } 51 } 52 void build(int c ,int l, int r) 53 { 54 tree[c].l = l ; 55 tree[c].r = r ; 56 tree[c].m = (l+r)/2; 57 if(l == r) 58 { 59 tree[c].maxn = sum[l]; 60 tree[c].s = l ; 61 return ; 62 } 63 build(L(c),l,tree[c].m); 64 build(R(c),tree[c].m+1,r); 65 pushup(c); 66 } 67 LL maxa; 68 int site; 69 void find(int c, int l , int r) 70 { 71 //printf("%d %d %d %d %d\n",c,tree[c].l,tree[c].r,l,r); 72 if(r < l ) 73 return ; 74 if(l <= tree[c].l && r >= tree[c].r) 75 { 76 if(tree[c].maxn > maxa) 77 { 78 maxa = tree[c].maxn; 79 site = tree[c].s; 80 } 81 return ; 82 } 83 if(l <= tree[c].m) 84 find(L(c),l,r); 85 if(r > tree[c].m) 86 find(R(c),l,r); 87 } 88 int main(){ 89 int n , k; 90 scanf("%d %d",&n,&k); 91 int temp ; 92 a[0] = 0 ; 93 for(int i = 1; i <= n;i ++) 94 { 95 scanf("%d",&temp); 96 a[i] = a[i-1] + temp; 97 } 98 for(int i = 1 ;i <= n-k+1; i ++) 99 { 100 sum[i] = a[i+k-1] - a[i-1]; 101 } 102 build(1,1,n-k+1); 103 LL ans = -1e9; 104 int a, b ; 105 for(int i =1 ;i <= n-k+1;i ++) 106 { 107 maxa = -1e9 ; 108 site = 0 ; 109 find(1,i+k,n-k+1); 110 if(sum[i] + maxa > ans) 111 { 112 ans = sum[i] + maxa; 113 a= i ; 114 b = site; 115 } 116 } 117 printf("%d %d\n",a,b); 118 return 0; 119 }
View Code
2)由第一种思路突然想到还可以预处理出来 i 以后 的最大值是多少,位置是多少,这样就可以直接dp了
1 // File Name: 332b.1.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月30日 星期三 10时13分41秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 #define maxn 200050 26 using namespace std; 27 LL a[maxn]; 28 LL sum[maxn]; 29 LL m[maxn]; 30 int s[maxn]; 31 int n , k ; 32 int main(){ 33 scanf("%d %d",&n,&k); 34 a[0] = 0 ; 35 int temp ; 36 for(int i = 1;i <= n;i ++) 37 { 38 scanf("%d",&temp); 39 a[i] =a[i-1]+ temp; 40 } 41 int p = n - k + 1; 42 for(int i = 1;i <= p ; i ++) 43 { 44 sum[i] = a[i+k-1] - a[i-1]; 45 } 46 m[p] = sum[p]; 47 s[p] = p ; 48 49 for(int i = p -1;i >= 1 ;i --) 50 { 51 if(sum[i] >= m[i+1]) 52 { 53 m[i] = sum[i]; 54 s[i] = i ; 55 }else{ 56 m[i] = m[i+1]; 57 s[i] = s[i+1]; 58 } 59 } 60 int a, b ; 61 LL maxa = -1e9 ; 62 for(int i =1 ;i <= p;i ++) 63 { 64 if(sum[i] + m[i+k] > maxa) 65 { 66 a = i ; 67 b = s[i+k]; 68 maxa = sum[i] + m[i+k]; 69 } 70 } 71 printf("%d %d\n",a,b); 72 return 0; 73 }
View Code
转载于:https://www.cnblogs.com/zyue/p/3877286.html
codeforces332B - Maximum Absurdity 线段数 or dp相关推荐
- [TJOI2011] 书架(线段数优化dp + 单调栈)
problem luogu-P1295 首先可以列出一个暴力 dpdpdp 转移. 设 f(i):f(i):f(i): 到 iii 为止划分若干组,每组最大值的和 的最小值. 然后枚举最后一组,即 i ...
- [CodeForces 332B]Maximum Absurdity[DP]
题目链接: [CodeForces 332B]Maximum Absurdity[DP] 题意分析: 寻找两个不重叠的长度为k的子串,使得它们之和最大. 解题思路: 第一想法是,处理出从这个点开始,长 ...
- Maximum Absurdity(dp思想+前缀和)
Maximum Absurdity 原题目:Maximum Absurdity 题解 处理长度为 k 的区间和用前缀和 处理不相交的两个区间和用 dp 思想,以 i 为界线,用四个数组分别记录位置 i ...
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp
D. Babaei and Birthday Cake 题目连接: http://www.codeforces.com/contest/629/problem/D Description As you ...
- 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛H题小Y与多米诺骨牌(线段树优化dp)
题意 题目链接:https://www.nowcoder.com/acm/contest/91/H 来源:牛客网 题解 设l[i]l[i]l[i]为向左推第iii个骨牌最远能影响到的骨牌的编号,r[i ...
- YBTOJ:采矿战略(线段树维护dp、树链剖分)
文章目录 题目描述 解析 代码 题目描述 所谓线段树维护dp,就是在线段树上维护dp (逃) 解析 把树剖一下后就变成了区间问题 考虑建一棵线段树,每一个结点都是一个背包 这样就能区间查询,也能带修了 ...
- 【CodeForces 332B --- Maximum Absurdity】递推
[CodeForces 332B --- Maximum Absurdity]递推 题目来源:点击进入[CodeForces 332B - Maximum Absurdity] Description ...
- 洛谷 P2657 [SCOI2009] windy数 数位DP
大家觉得写还可以,可以点赞.收藏.关注一下吧! 也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn 文章目录 P2657 [SCOI2009 ...
- 线段数单点更新——HDU 2795
对应HDU题目:点击打开链接 Billboard Time Limit: 20000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
最新文章
- FIS前端集成解决方案
- 【Leetcode】创建二叉树
- 动态创建 @ViewChild 导致运行时错误的原因分析
- JAXB vs XStream
- matlab没有找到图形用户界面,MATLAB中不能设计图形用户界面。
- C++ Iostreams 用法详解(二)标准输入输出
- 远程执行python脚本_python 远程执行服务器上的脚本
- 大数据笔记(二):HDFS原理知识
- 数据库练习题归纳整理
- MFC 控件清除内存
- EasySchedulerr大数据调度系统架构分析
- 组织行为学笔记-第一章
- 微信公众平台开发入门
- 2013年新会计准则常用会计科目表经典注释整理【最全】
- python列表求平均数_python 列表平均值
- 医院公厕智能化管理需要实现哪些功能
- speedoffice使用方法-Word如何分栏
- [转]深度剖析闪电网络
- 教师计算机培训心得博客,教师研修心得体会博客
- Google浏览器搜索页自定义图片
热门文章
- Linux下rpm安装软件
- Sublime text3 修改字体和行间距
- IntelliJ IDEA2017创建web工程并实现远程部署tomcat
- easyUI 的combobox如何获取除valueField和textField外的三个值
- 东南大学成贤学院计算机报名,2019上半年东南大学成贤学院全国计算机等级考试预报名通知...
- 【2021杭电多校赛】2021“MINIEYE杯”中国大学生算法设计超级联赛(5)签到题4题
- 大学计算机应用技术基础实践教程答案,【最新资料】大学计算机基础实践教程习题答案.doc...
- JavaScript函数内可以调用另一个函数(3)
- java fileio_java FileIO类
- python中文教程github_GitHub - Virile-Tao/python_data_structures_and_algorithms: Python 中文数据结构和算法教程...