Codeforces 1077F2 Pictures with Kittens (hard version)(DP+单调队列优化)

题目链接:Pictures with Kittens (hard version)

题意:给定n长度的数字序列ai,求从中选出x个满足任意k长度区间都至少有一个被选到的最大和。

题解:数据量5000,O(n^3)的DP不适用。需要加个单调队列优化。

注意每次是从$[i-k,i)$区间,选择加上ai。每次清空双向队列。

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 typedef long long ll;
 9 const int N=5000+10;
10 ll a[N],dp[N][N],ans=-1e18;
11 deque < pair<ll,int> > q;
12 
13 int main(){
14     int n,k,x;
15     scanf("%d%d%d",&n,&k,&x);
16     for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
17     for(int i=0;i<=n;i++)
18     for(int j=0;j<=n;j++)
19     dp[i][j]=-1e18;
20     dp[0][0]=0;
21     for(int j=1;j<=x;j++){
22         q.push_back(make_pair(0,0));
23         for(int i=1;i<=n;i++){
24             while(!q.empty()&&q.front().second<i-k) q.pop_front();
25             dp[i][j]=q.front().first+a[i];
26             while(!q.empty()&&q.back().first<=dp[i][j-1]) q.pop_back();
27             q.push_back(make_pair(dp[i][j-1],i));
28         }
29         q.clear();
30     }
31 
32     for(int i=n-k+1;i<=n;i++) ans=max(ans,dp[i][x]);
33     if(ans<0) ans=-1;
34 
35     printf("%lld\n",ans);
36     return 0;
37 }
View Code

猜你喜欢

转载自www.cnblogs.com/ehanla/p/9992060.html