喵哈哈村的魔法考试 Round #19 (Div.2) D & tyvj1305 单调队列优化的dp
题目链接:
题意:
给你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