Ilya Muromets
?Gym - 100513F
Ilya Muromets is a legendary bogatyr. Right now he is struggling against Zmej Gorynych, a dragon with?n?heads numbered from 1 to?n?from left to right.
Making one sweep of sword Ilya Muromets can cut at most?k?contiguous heads of Zmej Gorynych. Thereafter heads collapse getting rid of empty space between heads. So in a moment before the second sweep all the heads form a contiguous sequence again.
As we all know, dragons can breathe fire. And so does Zmej Gorynych. Each his head has a firepower. The firepower of the?i-th head is?fi.
Ilya Muromets has time for at most two sword sweeps. The bogatyr wants to reduce dragon's firepower as much as possible. What is the maximum total firepower of heads which Ilya can cut with at most two sword sweeps?
Input
The first line contains a pair of integer numbers?n?and?k?(1?≤?n,?k?≤?2·105) — the number of Gorynych's heads and the maximum number of heads Ilya can cut with a single sword sweep. The second line contains the sequence of integer numbers?f1,?f2,?...,?fn?(1?≤?fi?≤?2000), where?fi?is the firepower of the?i-th head.
Output
Print the required maximum total head firepower that Ilya can cut.
Examples
8 2
1 3 3 1 2 3 11 1
20
4 100
10 20 30 40
題意:
給你兩個數n和k,然后n個數,進行兩次操作,一次最多可以消除連續的K個數,然后剩余的數又變成連續的,問兩次操作后,消除的數的總和最大為多少。
題解:
dp[i][1]表示的是1-i的區間中,第一次操作能得到的最大值,因為i從k-n,每次加一,所以每次對最大值可能造成改變的只有新加進來的數,dp[i][1]=max(dp[i-1][1],sum[i]-sum[i-k]);
dp[i][1]表示的是1-i的區間中,兩次操作后能得到的最大值,dp[i][2]=max(dp[i-1][2],sum[i]-sum[i-k]+dp[i-k][1]);對于兩次操作,狀態轉移方程就是1- i-1區間兩次操作后最大值或者是新加入的i影響的區間sum[i]-sum[i-k]+1- i-k區間操作一次的最大值。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6 const int maxn=2e5+10;
7 int sum[maxn],a[maxn],dp[maxn][3];
8 int main()
9 {
10 int n,k;
11 scanf("%d%d",&n,&k);
12 for(int i=1;i<=n;i++)
13 {
14 scanf("%d",&a[i]);
15 sum[i]=sum[i-1]+a[i];
16 }
17 if(2*k>=n)
18 {
19 printf("%d\n",sum[n]);
20 return 0;
21 }
22 memset(dp,0,sizeof(dp));
23 for(int i=k;i<=n;i++)
24 {
25 dp[i][1]=max(dp[i-1][1],sum[i]-sum[i-k]);
26 dp[i][2]=max(dp[i-1][2],sum[i]-sum[i-k]+dp[i-k][1]);
27 // printf("%d %d %d\n",i,dp[i][1],dp[i][2]);
28 }
29 printf("%d\n",dp[n][2]);
30 return 0;
31 }
?
?