tyvj p1305 最大自序和
2016-07-05 20:31
190 查看
输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大。
例如 1,-3,5,1,-2,3
当m=4时,S=5+1-2+3=7
当m=2或m=3时,S=5+1=6
戳戳戳
一开始用的朴素的 错的 算法 。过了 9个点。
然后决定考虑 优化。
让我们来枚举子序列中的 最后一位,用s[i]表示 到a[i]的 序列和
所以 ans=s[i]-min(s[j])【j≥i-m】
因为sum是不变的所以我们只用求 最小的s【j】 即可
所以我们来维护一个单调序列满足
1.单调递增
2.栈中元素不能 超过m个
所以看代码吧
然后完美
例如 1,-3,5,1,-2,3
当m=4时,S=5+1-2+3=7
当m=2或m=3时,S=5+1=6
戳戳戳
一开始用的朴素的 错的 算法 。过了 9个点。
然后决定考虑 优化。
让我们来枚举子序列中的 最后一位,用s[i]表示 到a[i]的 序列和
所以 ans=s[i]-min(s[j])【j≥i-m】
因为sum是不变的所以我们只用求 最小的s【j】 即可
所以我们来维护一个单调序列满足
1.单调递增
2.栈中元素不能 超过m个
所以看代码吧
#include<cstdio> #include<algorithm> #include<cstring> //by mars_ch using namespace std; int n,m; int a; int ans; int sum; int f[300005]; int s[300005]; int main() { scanf("%d%d",&n,&m); int h=1,t=2; for(int i=1;i<=n;i++) { scanf("%d",&a); sum+=a; /************维护一个打掉递增的序列**************/ while(f[t-1]>=sum && t>h) { t--; } // printf("%d %d\n",t,sum); f[t]=sum; s[t++]=i; /************保证个数不超过m**************/ while(i-s[h]>m) h++; ans=max(ans,sum-f[h]); } printf("%d\n",ans); return 0; }
然后完美
相关文章推荐
- 单例模式
- sublime中使用ctags(详解)
- 简明 Vim 练级攻略
- 1746. DreamingAboutCarrots
- dd-wrt 定时重连 pppoe 更换ip地址
- Unity3D LOD Group
- 漫谈民生
- JAVA多线程同步:volatile,synchronized,Atomic... 比较
- HDU 4608 I-number(模拟)
- 调取系统相册和照相机选取图片
- 第137课: Spark面试经典系列之数据倾斜解决之Map 端Reduce及问题思考
- kafka+logstash搭建分布式消息订阅系统
- HTML5 Select标签基本使用
- Swift一些语法
- VR延迟优化
- io字节流复制媒体文件
- io字节流复制媒体文件
- io字节流复制媒体文件
- io字节流复制媒体文件
- ionic框架安装