码迷,mamicode.com
首页 > 其他好文 > 详细

TYVJ1305

时间:2014-08-24 23:33:43      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   os   io   for   div   log   amp   

题解上说这是DP+单调队列优化,我觉得这已经不算是DP了,只算是练习单调队列吧。
设dp[i]表示以a[i]结尾的不超过m个的最大的子段和
dp[i] = max(sum[i]-sum[i-k])1<=k<=m;        
因为sum[i]是不变的,所以稍微有点数学知识就可以得到
dp[i] = sum - min(sum[i-k]);
这就转换为求i-m到i中sum的最小值了
最后遍历dp取最大值就是答案了,时间复杂度O(n)空间O(n);

 

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #define INF 0x3f3f3f3f
 6 using namespace std;
 7 const int maxn = 300005;
 8 struct QUEUE
 9 {
10     int value;
11     int index;
12 }que[maxn];
13 int a[maxn],sum[maxn],dp[maxn];
14 int main()
15 {
16    // freopen("in.txt","r",stdin);
17     int n,m,f,r;
18     while(cin>>n>>m)
19     {
20         sum[0] = 0;
21         for(int i = 1;i<=n;++i)
22         {
23             scanf("%d",&a[i]);
24             sum[i] = sum[i-1]+a[i];
25         }
26         f = 1;r = 1;
27         que[1].value = 0;
28         que[1].index = 0;
29         for(int i = 1;i<=n;++i)
30         {
31             dp[i] = sum[i]-que[f].value;
32             while(f<=r && que[r].value>=sum[i])r--;
33             que[++r].value = sum[i];
34             que[r].index = i;
35             if(que[f].index<=i-m)f++;
36         }
37         int ans = -INF;
38         for(int i = 1;i<=n;++i)
39             ans = max(ans,dp[i]);
40         printf("%d\n",ans);
41 
42     }
43     return 0;
44 }

 

TYVJ1305

标签:style   blog   color   os   io   for   div   log   amp   

原文地址:http://www.cnblogs.com/GJKACAC/p/3933727.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!