HDU3415 Max Sum of Max-K-sub-sequence (DP+單調佇列)
題目連結:
http://acm.hdu.edu.cn/showproblem.php?pid=3415
題意:
給定一個長度為n的環,求其中一個長度小於等於k的區間,使其和最大,輸出最大和,區間的左右端點
分析:
直接想到暴力 dp[i]= sum[i] - sum[i-k+1+j] (0<=j<=k);
但是很明顯暴力會超時,就想到用單點佇列來維護,一個sum陣列,
使其sum儘量小的在前面.處理的時候要將環展開,sum存的是字首和。
程式碼如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 100010;
int a[maxn*2],sum[maxn*2];
int main()
{
int t,n,k;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&k);
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++){
scanf("%d",a+i);
sum[i]=sum[i-1]+a[i];
a[i+n]=a[i];
}
for(int i=n+1;i<=2*n;i++)
sum[i]=sum[i-1]+a[i];
deque<int >Q;
int ans = -1000000000,st=0,ed=0;
for(int i=1;i<=n+k-1;i++){
while(!Q.empty()&&sum[i-1]<sum[Q.back()])//保持佇列的單調性
Q.pop_back();
while(!Q.empty()&&Q.front()<i-k)//超過k的長度則消除佇列前面的元素
Q.pop_front();
Q.push_back(i-1);
if(sum[i]-sum[Q.front()]>ans){
ans=sum[i]-sum[Q.front()];
st=Q.front()+1;
ed=i;
}
}
if(ed>n) ed-=n;
printf("%d %d %d\n",ans,st,ed);
}
return 0;
}
相關文章
- hdu3415 單調佇列求區間最大和佇列
- HDU 3530 Subsequence (dp+單調佇列)佇列
- poj3017 dp+單調佇列佇列
- 單調佇列佇列
- 單調棧/單調佇列佇列
- 單調佇列雙端佇列佇列
- 單調棧 和 單調佇列佇列
- 單調棧和單調佇列佇列
- POJ 2823 單調佇列佇列
- hdu 3415 單調佇列佇列
- HDU 3530 單調佇列佇列
- hdu 3401 單調佇列+DP佇列
- hdu 4122 單調佇列佇列
- 單調佇列最佳化 DP佇列
- bzoj1597: [Usaco2008 Mar]土地購買(斜率優化+Dp+單調佇列)優化佇列
- POJ 3017 單調佇列dp佇列
- hdu4374單調佇列+dp佇列
- 佇列-單端佇列佇列
- noi.ac #289. 電梯(單調佇列)佇列
- 多重揹包問題的單調佇列優化佇列優化
- HDU3530 單調佇列的應用佇列
- C語言 簡單的佇列(陣列佇列)C語言佇列陣列
- hdu 4122Alice's mooncake shop(單調佇列)佇列
- [學習筆記] 單調佇列最佳化DP - DP筆記佇列
- POJ 2823Sliding Window(單調佇列水題)佇列
- RabbitMQ-簡單佇列MQ佇列
- 單向鏈式佇列佇列
- 棧,佇列,優先順序佇列簡單介面使用佇列
- POJ2823 Sliding Window (單調佇列的基本應用)佇列
- 多重揹包O(N*V)演算法詳解(使用單調佇列)演算法佇列
- laravel 佇列的簡單使用Laravel佇列
- 佇列_單向連結串列佇列
- 佇列、阻塞佇列佇列
- [ABC376E] Max × Sum 題解
- FZU 1894 單調佇列入門佇列
- 實現簡單延遲佇列和分散式延遲佇列佇列分散式
- BZOJ1044: [HAOI2008]木棍分割(dp 單調佇列)佇列
- 聯賽模擬測試18 A. 施工 單調佇列(棧)優化DP佇列優化