zoukankan      html  css  js  c++  java
  • 1324E

    题目大意:一天有h个小时,一个人喜欢睡觉,一共睡n次,每次都睡h个小时,开始时间为0,间隔a[i]或a[i]-1个小时开始睡第i次觉,每天都有一个最好时间区间,问这n次觉,最多有多少次是在最好时间内睡的。

    题解:定义状态dp[i][j]为第i次觉是在j时刻睡的,那么状态转移方程dp[i][j]=max(dp[i-1][(j-a[i]+h)%h],dp[i-1][(j-a[i]+1+h)%h]+

    check(j)。

    值得注意的是,不是每个状态都能够到达的,假设dp全部赋值为-1,当

    dp[i-1][(j-a[i]+h)%h]==-1&&dp[i-1][(j-a[i]+1+h)%h]==-1时,状态dp[i][j]就无法到达......

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=2E3+7;
    ll dp[N][N];
    ll arr[N];
    int main(){
        ll n,h,l,r;
        cin>>n>>h>>l>>r;
        for(ll i=1;i<=n;i++) cin>>arr[i];
        memset(dp,-1,sizeof dp);
        ll c1=arr[1]-1;
        ll c2=arr[1];
        dp[1][c1]=(c1>=l&&c1<=r ? 1:0);
        dp[1][c2]=(c2>=l&&c2<=r ? 1:0);
        ll ans=max(dp[1][c1],dp[1][c2]);
        for(ll i=2;i<=n;i++){
            for(ll j=0;j<h;j++){
                ll c1=(j-arr[i]+h)%h;
                ll c2=(j-arr[i]+1+h)%h;
                if(dp[i-1][c1]<0&&dp[i-1][c2]<0) continue ;
                dp[i][j]=max(dp[i][j],max(dp[i-1][c1],dp[i-1][c2])+(j>=l&&j<=r ? 1:0));
            }
        }
        for(ll i=0;i<h;i++) ans=max(ans,dp[n][i]);
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    BZOJ1006: [HNOI2008]神奇的国度
    弦图与区间图
    后缀自动机
    插头DP
    BZOJ3328: PYXFIB
    BZOJ2118: 墨墨的等式
    BZOJ3916: [Baltic2014]friends
    BZOJ1337: 最小圆覆盖
    BZOJ3784: 树上的路径
    代码模版
  • 原文地址:https://www.cnblogs.com/Accepting/p/12490712.html
Copyright © 2011-2022 走看看