SP283 NAPTIME - Naptime

SP283 NAPTIME - Naptime

题意:

在某个星球上,一天由N小时构成。我们称0-1点为第一个小时,1-2点为第二个小时,以此类推。在第i个小时睡觉能恢复Ui点体力。在这座星球上住着一头牛,它每天要休息B个小时,它休息的这B个小时可以不连续,可以分成若干段,但是在每一段的第一个小时不能恢复体力,从第二个小时开始才可以恢复体力。 为了身体健康,这头牛希望遵循生物钟,每天采用相同的睡觉计划。另外,因为时间是连续的,每天的第N个小时与下一天的第一个小时是相连的,这头牛只需要在N个小时内休息B个小时就够了。 请你给这头牛安排一个任务计划,使得它每天恢复的体力最多。

输入格式: 第一行一个整数T表示有T组测试数据 对于每一组测试数据,第一行为两个整数N与B,接下来N行每行一个整数Ui。(2 <= B < N <= 3830 , 0 <= Ui <= 200000)

输出格式: 对于每组输入数据,对应一行输出一个整数,表示答案。(注意:两组输出之间没有空行)

我们可以发现一些很显然的性质:如果第一小时的体力值能够恢复,当且仅当第n小时和第一小时都在睡觉,然而我们并不确定第n小时究竟是不是睡觉,所以就不知道应该怎样给第一天初始值了,但是如果我们将这一限制去除,那么无论第n小时在不在睡觉第一小时都不会回复体力值,这样就可以进行第一次的dp,但是样就会出现一个问题,如果第一小时和第n小时都在睡觉,那么就会少U[1]点体力值,这样的话我们就可以强制令第一小时和第n小时都在睡觉,再进行一次dp并且把U[1]加进去,两次dp取最大值,就是答案了。

 1 #include<iostream>
 2 #include<string>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<stack>
 7 #include<queue>
 8 #define maxn 4005
 9 using namespace std;
10 
11 inline int read()
12 {
13     char c=getchar();
14     int x=1,res=0;
15     while(c<'0'||c>'9')
16     {
17         if(c=='-')
18         x=-1;
19         c=getchar();
20     }
21     while(c>='0'&&c<='9')
22     {
23         res=res*10+(c-'0');
24         c=getchar();
25     }
26     return x*res;
27 }
28 
29 int t,n,m,ans;
30 int a[maxn];
31 int f[maxn][maxn][2],dp[maxn][maxn][2];
32 
33 int main()
34 {
35     t=read();
36     while(t--)
37     {
38         ans=0;
39         n=read();m=read();
40         for(int i=1;i<=n;i++)
41         {
42             a[i]=read();
43         }
44         memset(f,-0x3f,sizeof(f));
45         f[1][0][0]=0;f[1][1][1]=0;
46         for(int i=2;i<=n;i++)
47         {
48             for(int j=0;j<=m;j++)
49             {
50                 if(j>0) f[i][j][1]=max(f[i-1][j-1][0],f[i-1][j-1][1]+a[i]);
51                 f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]);
52             }
53         }
54         ans=max(f[n][m][1],f[n][m][0]);
55         memset(f,-0x3f,sizeof(f));
56         f[1][1][1]=a[1];
57         for(int i=2;i<=n;i++)
58         {
59             for(int j=0;j<=m;j++)
60             {
61                 if(j>0) f[i][j][1]=max(f[i-1][j-1][0],f[i-1][j-1][1]+a[i]);
62                 f[i][j][0]=max(f[i-1][j][0],f[i-1][j][1]);
63             }
64         }
65         ans=max(ans,f[n][m][1]);
66         printf("%d\n",ans);
67     }
68     return 0;
69 }
View Code

 

posted @ 2019-03-26 21:06  snowy2002  阅读(281)  评论(0编辑  收藏  举报