zoukankan      html  css  js  c++  java
  • CF-div3-627-E. Sleeping Schedule| dp

    思路

    状态转移方程

    dp[i][j] 表示第i个位置,在时间为j下的 好睡眠次数
    dp[i-1][j] 可以推出 dp[i][j+a[i]] 和 dp[i][j+a[i]-1];

    l,r时间段内:dp[i][u] = max(dp[i][u],dp[i-1][j] + 1); // u表示 j-a[i] 或者 j-(a[i]+1)
    非l,r时间内:dp[i][u] = max(dp[i][u],dp[i-1][j]);

    另外dp[i][j]初值设置为-1,因为前一时刻dp[i-1][j]下在j时刻可能未醒来,即前一个状态未到达,那么当前状态也不可能到达了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 2100;
    int a[maxn];
    int dp[maxn][maxn];
    int n,h,l,r;
    
    int main(){
    	cin>>n>>h>>l>>r;
    	for(int i=1;i<=n;i++){
    		cin>>a[i];
    	}
    	//判断是否经历过dp[i-1][j] 没经历过肯定不可退出下一阶段 
    	memset(dp,-1,sizeof dp); //表示当前状态下未醒来:有状态是无法达到的 设置初态为-1未到达过  
    	dp[0][0] = 0; //只能由初状态得来 
    	for(int i=1;i<=n;i++){
    		for(int j=0;j<h;j++){
    			if(dp[i-1][j] == -1) continue; //没到达过i-1,j肯定不可推当当前 
    			int u = (j + a[i])%h;
    			int v = (j + a[i] - 1)%h;
    			if(u>=l && u<=r){
    				dp[i][u] = max(dp[i][u],dp[i-1][j] + 1);
    			}else dp[i][u] = max(dp[i][u],dp[i-1][j]);
    			if(v>=l && v<=r){
    				dp[i][v] = max(dp[i][v],dp[i-1][j] + 1);
    			}else dp[i][v] = max(dp[i][v],dp[i-1][j]);
    		}
    	}
    	int ans = 0;
    	for(int j=0;j<h;j++){
    		ans = max(ans,dp[n][j]);
    	}
    	cout<<ans;
    } 
    
  • 相关阅读:
    225. 用队列实现栈
    415. 字符串相加
    rabbitmq的基本使用
    3. 无重复字符的最长子串
    面试题59
    面试题30. 包含min函数的栈
    面试题09. 用两个栈实现队列
    287. 寻找重复数
    1137. 第 N 个泰波那契数
    70. 爬楼梯
  • 原文地址:https://www.cnblogs.com/fisherss/p/12724820.html
Copyright © 2011-2022 走看看