CodeForces-1324Eスリープスケジュール(dp)

質問の意味:n項目、t = a [i]またはa [i] -1を選択する順序、つまりs =(s + t)、[l、r]のsは何回ですか?

単純なdp、dp [i] [j]:最初のi個のアイテムをjに選択するのに最適な回数。

dp [i] [j] = max(dp [i-1] [(ja [i] + h)%h]、dp [i-1] [(ja [i] +1)%h]);

jが区間[l、r]にあるかどうかを判断する際に、dp [i] [j] ++にある場合。

詳細については、コードを参照してください。

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e3+3;
int n,h,l,r;
int a[2003];
int dp[maxn][maxn];
int main() {
	scanf("%d%d%d%d",&n,&h,&l,&r);
	for(int i=1;i<=n;i++){
		scanf("%d",a+i);
 	}
        //记得初始化,第i个选择只能由第i-1个选择转移过来
 	memset(dp,0xcf,sizeof(dp));
 	dp[0][0]=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<h;j++){
			int x=(j-a[i]+h)%h;
			int y=(j-a[i]+1+h)%h;
			dp[i][j]=max(dp[i-1][x],dp[i-1][y]);
			if(l<=j&&j<=r) dp[i][j]++;
		}
	}
	int ans=0;
	for(int i=0;i<h;i++) ans=max(ans,dp[n][i]);
	cout<<ans<<endl;
	return 0;
}

 

おすすめ

転載: blog.csdn.net/qq_44132777/article/details/104859637