codeforces 1077F2

题解:
显然可以dp[i][j]表示到第i个,选了j个的最优解

单调队列优化

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define pii pair<ll,int>
 4 #define mp(a,b) make_pair(a,b)
 5 #define maxn 5005
 6 using namespace std;
 7 int n,k,x;
 8 struct Que
 9 {
10     int l,r;
11     pii a[maxn];
12     void init(){l=r=0;}
13     bool empty(){return l==r;}
14     void push(pii x)
15     {
16         while(!empty()&&a[r]<x)r--;
17         a[++r]=x;
18     }
19     pii top(){return a[l+1];}
20     void pop(){l++;}
21 }q;
22 int a[maxn];
23 ll dp[maxn][maxn];
24 int main()
25 {
26     scanf("%d%d%d",&n,&k,&x);
27     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
28     if(n>=(x+1)*k)
29     {
30         puts("-1");exit(0);
31     }
32     for(int i=0;i<=n;++i)
33         for(int j=0;j<=x;++j)dp[i][j]=-(ll)1e17;
34     dp[0][0]=0;
35     for(int j=1;j<=x;++j)
36     {
37         q.init();
38         q.push(mp(0,0));
39         for(int i=1;i<=n;++i)
40         {
41             while(!q.empty()&&q.top().second<i-k)q.pop();
42             int t=q.top().second;
43             if(dp[t][j-1]>=0)dp[i][j]=dp[t][j-1]+a[i];
44             q.push(mp(dp[i][j-1],i));
45         }
46     }
47     ll ans=0;
48     for(int i=n-k+1;i<=n;++i)ans=max(ans,dp[i][x]);
49     printf("%I64d\n",ans);
50     return 0;
51 }
View Code

猜你喜欢

转载自www.cnblogs.com/uuzlove/p/10628841.html