Description
On a planet, a day consists of N hours. We call for the first hour 0-1 points, 1-2 points for the second hour, and so on.
In the i-th point Ui hours sleep to restore strength. Lived on this planet a cow, it is to break B hours a day, the rest of it
This may not be continuous hours B, it can be divided into several segments, but not recuperate the first hour of each segment, from the second small
At the beginning before they can regain their strength. For good health, the cow that wish to follow the biological clock, sleep the same program every day. another
Outside , because the time is continuous, the N-th day, the hour and the first hour of the day are contiguous, cow only in small N
When resting B within hours is enough. Please give this cow arrange a schedule, make it physical recovery up to a day.
N<=3830 0<Ui<200000
Sol
For the processing loop we often seek to copy double the range solution
However, the upper limit of a degree of complexity of this question O (n- 2 ), can not be so, but it is not suitable interval dp, dp is more suitable for linear
Observe problems found can be divided into two cases:
- N-th hour and one hour of continuous rest
- N-th hour and one hour resting discontinuous
Whether the rest of the time is a key, so we have a state:
f [i] [j] [0/1] ~ i h denotes 1 h and j of a total of rest hours without a break i (0) / rest (1) the maximum strength that can be obtained
Transfer equation: f [i] [j] [0] = max (f [i-1] [j] [0], f [i-1] [j] [1])
f[i][j][1]=max(f[i-1][j-1][1]+U[i],f[i-1][j-1][0]) (j>0)
For both cases, we were to make an initial value of dp
- f[1][1][1]=U[1]
- f[1][1][0]=0,f[1][0][0]=0
Others are negative infinity (because it is not provided)
Goal is
- max(f[n][b][1],f[n][b][0])
- f[n][b][1]
Code
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; const int N=3831; int f[N][N][2],d[N],n,b,T; void dp() { for(int i=2;i<=n;i++) for(int j=0;j<=b;j++) { f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]); if(j) f[i][j][1]=max(f[i-1][j-1][1]+d[i],f[i-1][j-1][0]); } } int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&b); for(int i=1;i<=n;i++) scanf("%d",&d[i]); memset(f,0x80,sizeof(f)); f[1][1][1]=f[1][0][0]=0; dp(); int ans=max(f[n][b][0],f[n][b][1]); memset(f,0x80,sizeof(f)); f[1][1][1]=d[1]; dp(); printf("%d\n",max(ans,f[n][b][1])); } return 0; }