比赛的时候E题知道是个DP。。。但没做出来。。。
每次做DP的题最大的困扰就是不知道设一个怎样的数组来表示
设一个dp[i][j]
表示在第 i 次在第 j 时间段睡觉时最大的好处值
那么
如果(j+a[i])%h在l~r之间
dp[ i ][( j + a[i] )%h]=max(dp[ i ][( j + a[i] )%h] , d[ i-1 ][ j ] + 1)
如果不在
dp[ i ][( j + a[i] )%h]=max( d[ i ][( j + a[i] )%h] ,0 , d[ i - 1][ j ])
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[2005],inf=99999999;
int d[2005][2005];
void init()
{
for(int i=0;i<2002;i++)
{
for(int j=0;j<2002;j++)
{d[i][j]=-1;}
}
}
int main()
{
int n,h,l,r;
cin>>n>>h>>l>>r;
for(int i=1;i<=n;i++)
{cin>>a[i];}
init();//初始化f数组
if(a[1]>=l&&a[1]<=r)
{d[1][a[1]]=1;}
else
{d[1][a[1]]=0;}
if(a[1]-1>=l&&a[1]-1<=r)
{d[1][a[1]-1]=1;}
else
{d[1][a[1]-1]=0;}
for(int i=2;i<=n;i++)
{
for(int j=0;j<=h;j++)
{
int op=a[i];
if(d[i-1][j]!=-1)
{
int u=(j+op)%h;
if(u>=l&&u<=r)
{d[i][u]=max(d[i][u],d[i-1][j]+1);}
else
{d[i][u]=max(d[i][u],0);
d[i][u]=max(d[i][u],d[i-1][j]);}
op--;
u=(j+op)%h;
if(u>=l&&u<=r)
{d[i][u]=max(d[i][u],d[i-1][j]+1);}
else
{d[i][u]=max(d[i][u],0);
d[i][u]=max(d[i][u],d[i-1][j]);}
}
}
}
int maxx=-1;
for(int j=0;j<=h;j++)
{maxx=max(maxx,d[n][j]);}
cout<<maxx<<endl;
return 0;
}