• 洛谷 P1280 尼克的任务 ( 线性DP )


    题意 :  尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成。尼克的一个工作日为N分钟,从第一分钟开始到第N分钟结束。当尼克到达单位后他就开始干活。如果在同一时刻有多个任务需要完成,尼克可以任选其中的一个来做,而其余的则由他的同事完成,反之如果只有一个任务,则该任务必需由尼克去完成,假如某些任务开始时刻尼克正在工作,则这些任务也由尼克的同事完成。如果某任务于第P分钟开始,持续时间为T分钟,则该任务将在第P+T-1分钟结束。写一个程序计算尼克应该如何选取任务,才能获得最大的空暇时间。

    分析 : 

    根据题意,不妨试试定义 dp[i] = 1~i 这个时间段尼克最大空闲时间

    但是会发现一个问题,如果是这样定义的话,那么如果当前点 i 是

    有任务的话那么,肯定是从 dp[i + T] 这个状态转移到 dp[i] 的。

    具体的含义就是,选择做 i 这个工作,显然在 i 这个工作的工作时间

    段内是没有空闲时间的,那么 i 点的空闲时间就要从做完 i 之后的

    时间点中选择最优的进行转移。所以嘚从后往前 DP ,当然这个是

    取决于 DP 状态的定义,洛谷题解上有从前向后的 DP,可以去看一下

    那么改变一下定义有 dp[i] = i~N 这个时间段尼克的最大空闲时间

    那么对于每一个点,有两种情况

    ① i 这个点是某一任务的开头 dp[i] = max( dp[i], dp[i+T] )

    ② i 这个点没有任务 dp[i] = dp[i+1] + 1、表示当前空闲时间相比上一个点 + 1

    那么这样子,对于每一个有任务的点,往后跳 T 个时间点的状态转移

    就能做到如果选择了这个任务,那么将失去多少时间,得到多少时间的空闲

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e4 + 10;
    struct ASSIGN{
        int st, en, len;
        bool operator < (const ASSIGN &rhs)const{
            return this->st > rhs.st;
        };
    }arr[maxn];
    int dp[maxn];
    bool flag[maxn];
    int N, K;
    
    int main(void)
    {
        memset(dp, 0, sizeof(dp));
        memset(flag, false, sizeof(flag));
    
        scanf("%d %d", &N, &K);
        for(int i=0; i<K; i++)
            scanf("%d %d", &arr[i].st, &arr[i].len),
            arr[i].en = arr[i].st + arr[i].len - 1,
            flag[arr[i].st] = true;
        sort(arr, arr+K);
    
        int cur = 0;
        for(int i=N; i>=1; i--){
            if(!flag[i]) dp[i] = dp[i+1] + 1;
            else{
                while(arr[cur].st == i){
                    dp[i] = max(dp[i], dp[arr[cur].en+1]);
                    cur++;
                }
            }
        }
    
    
        return !printf("%d
    ", dp[1]);
    }
    View Code
  • 相关阅读:
    [翻译] SVProgressHUD
    使用CoreData [4]
    Android学习笔记之AndroidManifest.xml文件解析
    Android 版本自动更新
    两个android程序间的相互调用(apk互调)
    Android 生成含签名文件的apk安装包
    【已解决】Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory 8
    android adt与android sdk有什么关系,他们在开发中各起到什么作用
    Please ensure that adb is correctly located at……问题解决方案
    安装Android SDK时,点击SDK Manager.exe闪退,并且jdk的环境变量是对的。
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/8907269.html
Copyright © 2020-2023  润新知