喵哈哈村的魔法考试 Round #19 (Div.2) D & tyvj1305 单调队列优化的dp

题目链接:

http://qscoj.cn/problem/130/

题意:

给你n个数a[1],a[2],a[3],......,a[n],然后再给你一个k。

定义sum[l,r]=a[l]+a[l+1]+a[l+2].....+a[r-1]+a[r],但是必须满足r-l+1<=k

思路:

http://blog.csdn.net/oiljt12138/article/details/51174560

f(i) = sum[i]-min{sum[k]|i-M≤k≤i} 

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define MS(a) memset(a,0,sizeof(a))
 5 #define MP make_pair
 6 #define PB push_back
 7 const int INF = 0x3f3f3f3f;
 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 9 inline ll read(){
10     ll x=0,f=1;char ch=getchar();
11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
13     return x*f;
14 }
15 //////////////////////////////////////////////////////////////////////////
16 const int maxn = 1e6+10;
17 
18 int s[maxn];
19 
20 struct node{
21     int v,id;
22 }q[maxn];
23 
24 int main(){
25     int n,m;
26     cin >> n >> m;
27     for(int i=1; i<=n; i++){
28         int x = read();
29         s[i] = x+s[i-1];
30     }
31 
32     int head=0,tail=0;
33     q[0].v=0,q[0].id=0;
34     ll ans = -INF;
35     for(int i=1; i<=n; i++){
36         ll re = s[i];
37         re -= q[tail].v;
38         ans = max(ans,re);
39         while(tail<=head && q[head].v>s[i]) head--;
40         q[++head].v = s[i];
41         q[head].id = i;
42         while(tail<=head && q[tail].id<=i-m) tail++;
43     }
44 
45     cout << ans << endl;
46     
47 
48     return 0;
49 }
50 
51 // http://www.tyvj.cn/p/1305
原文地址:https://www.cnblogs.com/yxg123123/p/6837882.html