每一次选择(a_i / a_i-1)都会对以后的选择有影响, 那就是经典的DP问题, 找最优子结构, 设(dp_{i,j})为已经经过(i)次, 有(j)次选择了(a_i-1)的最优次数, 设(sum_i=sum_0^i a_i), 得到状态转移:
(dp_{i+1, j} = max(dp_{i, j} + l≤(sum-j)\%h ≤ r))(0≤j≤i))
(dp_{i+1, j+1} = max(dp_{i, j} + l≤(sum-j-1)\%h ≤ r))(0≤j≤i))
#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
typedef long long LL;
typedef pair<int,int> pii;
const int INF = 0x3f3f3f3f;
int isgood(int t, int l, int r) {
return t >= l && t <= r;
}
void run_case() {
int n, h, l, r;
cin >> n >> h >> l >> r;
vector<vector<int>> dp(n+1, vector<int>(n+1, -INF));
dp[0][0] = 0;
vector<int> a(n);
for(auto &x: a) cin >> x;
int sum = 0;
for(int i = 0; i < n; ++i) {
sum += a[i];
for(int j = 0; j <= i; ++j) {
dp[i+1][j] = max(dp[i+1][j], dp[i][j] + isgood((sum-j)%h, l, r));
if(j < n) dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j] + isgood((sum-j-1)%h, l, r));
}
}
cout << *max_element(dp[n].begin(), dp[n].end());
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(2);
//int t; cin >> t;
//while(t--)
run_case();
cout.flush();
return 0;
}