题意:
n,h,l,r,给n个时间间隔,从0开始睡觉,一天共有h小时,每次睡ai 或者 ai-1段时间。(n<2000,h<2000)
如果在l 和 r段时间入睡 那么满意度+1,问满意度最高多少?
题解:
最近都在做dp的题,这题一看数据范围就知道是个二维关于n和h的dp,打到E题还剩下1小时感觉这题稳了,状态转移方程也很快推了出来。有点像01背包,设dp[i][j]为前i个当前时间为j的最大满意度,
前i-1选择a[i]到dp[i][j],就是dp[i-1][(j-a[i]+h)%h],
或者选a[i]-1,就是dp[i-1][(j-(a[i]-1)+h)%h]。
dp[i][j]=max(dp[i-1][(j-(a[i]-1)+h)%h],dp[i-1][(j-a[i]+h)%h]);
if(j>=l&&j<=r) dp[i][j]++;
就是对不合法状态不知道怎么处理,看了题解才知道,一开始dp全赋值-1,就是不合法的状态。
dp[0][0]赋值为0,以便i=1转移。
dp这种东西果然做多了就很有感觉,继续加油吧!
代码:
#include<bits/stdc++.h> #define endl ‘\n‘ using namespace std; typedef long long ll; typedef double db; typedef pair<int,int> pii; typedef vector<int> vi; #define check system("pause") #define all(x) (x).begin(),(x).end() #define de(a) cout<<#a<<" = "<<a<<endl #define dd(a) cout<<#a<<" = "<<a<<" " #define mp make_pair #define pb push_back #define fi first #define se second #define lowbit(a) ((a)&-(a)) #define INF 0x3f3f3f3f const ll mod = 1e9+7; const int N = 2e3+20; #define dep(i,a,b) for(int i=(a);i>=(b);i--) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define mes(p,b) memset(p,b,sizeof(p)) #define sz(x) int(x.size()) ll dp[N][N],n,h,l,r,a[N],ans=0; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n>>h>>l>>r; rep(i,1,n) cin>>a[i]; mes(dp,-1); dp[0][0]=0; rep(i,1,n) rep(j,0,h-1){ if(dp[i-1][(j-(a[i]-1)+h)%h]!=-1) dp[i][j]=dp[i-1][(j-(a[i]-1)+h)%h]; if(dp[i-1][(j-a[i]+h)%h]!=-1) dp[i][j]=max(dp[i][j],dp[i-1][(j-a[i]+h)%h]); if(dp[i][j]!=-1&&j>=l&&j<=r) dp[i][j]++; } rep(i,0,h-1) ans=max(ans,dp[n][i]); cout<<ans; return 0; }
codeforces 627 div3 E. Sleeping Schedule (dp)
原文:https://www.cnblogs.com/FZUlh/p/12487209.html