P1280 尼克的任务

P1280 尼克的任务 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

 

按正常思路来想:

首先令dp[ i ]为到第i分钟的最多空闲时间,讲第i分钟结尾的工作时间存入 v[ i ]。 

容易获得代码:

    for(int i=1;i<=m;i++)
    {
        int st=read(),t=read();
        v[st].pb(t);
    }for(int i=1;i<=n;i++)
    {
        if(!v[i].size()) dp[i]=dp[i-1]+1;
        else for(auto x:v[i]) dp[i+x]=max(dp[i],dp[i+x]);
    }
    printf("%d",dp[n]);

但显然这是dp[i]推dp[i+x],显然是不符合dp的 

 

 

那么为什么倒着推?

此时有任务(不在工作状态)就必须选,有很多个就选一个,所以当这个时间只有一个状态开始的时候,我们是没有任何的话说的

但是如果有很多的任务同时开始,我们要选取最优的那个取决这个任务结束后的情况,但是任务结束后的情况我们之前有没有推过,所以我们要倒着推

dp[i]=max(dp[i],dp[i+x]),正推的话dp[i+x]是不知道的

 

倒推:dp[i]为第i分钟开始所能获得的最多空闲时间

    for(int i=1;i<=m;i++)
    {
        int st=read(),t=read();
        v[st].pb(t);
    }
    for(int i=n;i;i--)
    {
        if(!v[i].size()) dp[i]=dp[i+1]+1;
        else for(auto x:v[i]) dp[i]=max(dp[i],dp[i+x]);
    }
    printf("%d",dp[1]);

完整code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pb push_back   
#define popb pop_back  
#define fi first
#define se second
const int N=1e4+10;
//const int M=;
//const int inf=0x3f3f3f3f;     
//const ll INF=0x3ffffffffffff;
int T,n,m,dp[N];
vector<int> v[N];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
int main()
{
//    freopen("","r",stdin);
//    freopen("","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=m;i++)
    {
        int st=read(),t=read();
        v[st].pb(t);
    }
    for(int i=n;i;i--)
    {
        if(!v[i].size()) dp[i]=dp[i+1]+1;
        else for(auto x:v[i]) dp[i]=max(dp[i],dp[i+x]);
    }
    printf("%d",dp[1]);
    return 0;
}

 

posted @ 2023-02-27 22:19  QAQ啥也不会  阅读(17)  评论(0编辑  收藏  举报