l i n k link l i n k
question meaning: a length ofnnAn array of n , you can take several segments from it, and the length of each segment cannot exceedKKK , what is the maximum value of several segments?
题解:
d p [ i ] [ 0 ] = m a x ( d p [ i − 1 ] [ 0 ] , d p [ i − 1 ] [ 1 ] ) dp[i][0] = max(dp[i-1][0],dp[i-1][1]) dp[i][0]=max(dp[i−1][0],dp[i−1][1]);
d p [ i ] [ 1 ] = m a x ( d p [ k ] [ 0 ] + s u m [ i ] − s u m [ k ] ) dp[i][1] = max(dp[k][0]+sum[i]-sum[k]) dp[i][1]=max(dp[k][0]+sum[i]−sum[k])其中 ( i − K < = k < = i ) (i-K<=k<=i) (i−K<=k<=i);
化简得: d p [ i ] [ 1 ] = s u m [ i ] − m a x ( d p [ k ] [ 0 ] − s u m [ k ] ) dp[i][1] = sum[i]-max(dp[k][0]-sum[k]) dp[i][1]=sum[i]−max(dp[k][0]−sum[k])其中 ( i − K < = k < = i ) (i-K<=k<=i) (i−K<=k<=i ) ;
and wheremax (dp [k] [0] − sum [k]) max(dp[k][0]-sum[k])max(dp[k][0]−s u m [ k ] ) can be obtained by pawning the queue.
c o d e : code: code:
#include <bits/stdc++.h>
#define ll long long
#define pi pair<int,int>
#define mk make_pair
#define pb push_back
using namespace std;
const int maxn = 1e5+100;
ll a[maxn],q[maxn],sum[maxn],dp[maxn][2];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%lld",a+i),sum[i] = sum[i-1] + a[i];
k+=1;
int head = 1,tail = 0;
for(int i=1;i<=n;i++)
{
dp[i][0] = max(dp[i-1][0],dp[i-1][1]);
while(head <= tail && i-q[head]+1 > k)++head;
while(head <= tail && dp[q[tail]][0] - sum[q[tail]] < dp[i][0] - sum[i])--tail;
q[++tail] = i;
if(i < k)dp[i][1] = sum[i];
else dp[i][1] = sum[i] + dp[q[head]][0] - sum[q[head]];
}
printf("%lld\n",max(dp[n][0],dp[n][1]));
return 0;
}