传送门
题意:
vova有一个睡眠时间安排表。一天有h个小时,在[l,r]这短时间内睡醒vova会增加幸福值(初始为0),有n个睡眠时间,a1…ai…an. ai代表在ai时间后睡醒。vova可选择睡ai或ai-1时间。问vova最多能得到多少幸福值。
思路:
后面睡醒的时间由前面睡醒的时间影响。所以用dp来做这个题,dp[i,j],i代表每个时间段,j代表i时间段内j小时的幸福值。
输出最后一段h时间内的最大值即可。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=2e3+5;
int hour[MAXN],dp[MAXN][MAXN];//第i短第j个小时的幸福值
int main()
{
int n,h,l,r;
scanf("%d%d%d%d",&n,&h,&l,&r);
for(int i=1;i<=n;i++)
scanf("%d",&hour[i]);
memset(dp,-0x3f3f3f3f,sizeof(dp));//memset里用初始化必须是十六进制
dp[0][0]=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<h;j++)//枚举当前状态的可能幸福值
{
int hj=(hour[i]+j)%h;//hour[i]后才醒
dp[i][hj]=max(dp[i-1][j]+(hj>=l && hj<=r),dp[i][hj]);
hj=(hour[i]+j-1)%h;//hour[i]-1后才醒
dp[i][hj]=max(dp[i-1][j]+(hj>=l && hj<=r),dp[i][hj]);
}
}
int ans=0;
for(int j=0;j<h;j++)
ans=max(ans,dp[n][j]);
printf("%d",ans);
return 0;
}