思路
暴搜 + 记忆化即可。
题意
小v 在第 i 次醒来后(最开始是醒的)的第 a[i] 小时 或者 a[i] - 1 小时睡觉,每次睡一天(这个一天的定义是 h 时)。
令 小v 睡觉的时间点为 x ,如果 L ≤ X ≤ R,就睡得好。
问最多能睡得好多少次。
CODE
#include <bits/stdc++.h>
#define dbg(x) cout << #x << "=" << x << endl
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
template<class T>inline void read(T &res)
{
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
namespace _buff {
const size_t BUFF = 1 << 19;
char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
char getc() {
if (ib == ie) {
ib = ibuf;
ie = ibuf + fread(ibuf, 1, BUFF, stdin);
}
return ib == ie ? -1 : *ib++;
}
}
int qread() {
using namespace _buff;
int ret = 0;
bool pos = true;
char c = getc();
for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
assert(~c);
}
if (c == '-') {
pos = false;
c = getc();
}
for (; c >= '0' && c <= '9'; c = getc()) {
ret = (ret << 3) + (ret << 1) + (c ^ 48);
}
return pos ? ret : -ret;
}
const int maxn = 4007;
int a[maxn];
int n,h,l,r;
int f[maxn][maxn];
int dfs(int x, int now) {
//dbg(now);
if(x > n) {
return 0;
}
if(f[x][now] != -1) {
return f[x][now];
}
int temp = (now + a[x]) % h;
int res = 0;
int q = 0;
if(temp <= r && temp >= l) {
q++;
}
int res1 = q + dfs(x + 1, temp);
q = 0;
temp = (now + a[x] - 1) % h;
if(temp <= r && temp >= l) {
q++;
}
int res2 = q + dfs(x + 1, temp);
res = max(res1, res2);
f[x][now] = res;
return res;
}
int main()
{
scanf("%d %d %d %d",&n, &h, &l, &r);
for ( int i = 1; i <= n; ++i ) {
read(a[i]);
}
memset(f, -1, sizeof(f));
printf("%d
",dfs(1,0));
return 0;
}