• P1280 尼克的任务


    题意:

    尼克的一个工作日为N分钟,从第一分钟开始到第N分钟结束。

    当尼克到达单位后他就开始干活。如果在同一时刻有多个任务需要完成,

    尼克可以任选其中的一个来做,而其余的则由他的同事完成,反之如果只有一个任务,

    则该任务必需由尼克去完成,假如某些任务开始时刻尼克正在工作,

    则这些任务也由尼克的同事完成。如果某任务于第P分钟开始,持续时间为T分钟,

    则该任务将在第P+T-1分钟结束。

    写一个程序计算尼克应该如何选取任务,才能获得最大的空暇时间

    一道普及难度的题

    我居然想不到正解!!

    我TMDP太弱了。。。

    还是要多练啊。。。

    设f[i]:1~i的最大空闲时间,但是,第i时刻的最大空闲时间是和后面i+1选择任务的持续时间的时刻有关系的(有后效性),那么,正着找肯定是不行的,

    我们来试一下倒着搜,即设f[i]表示i~n的最大空闲时间,经尝试,发现是完全可行的,可以列出动态转移方程如下

    (本时刻无任务)f[i]=f[i+1]+1;//继承上一个时刻的最大空闲时间后+1

    (本时刻有任务)f[i]=max(f[i],f[i+a[sum])//a[sum]表示在这个时刻的任务的持续时间,找出选择哪一个本时刻任务使空闲时间最大化

    那么既然是倒着搜,从后往前的任务对应的开始时间自然也要反过来,从大到小排序(同时也是为了把相同开始时间的任务放到一起),

    当然在进行状态刷新的时候别忘了拿sum不断计一下已经到哪一个任务了

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define love_nmr 0
    int n,k;
    struct node
    {
        int beg;
        int dis;
        friend bool operator < (const node &a,const node &b)
        {
            return a.beg>b.beg;
        }
    }w[10505];
    int f[10505];
    int t[10505];
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>n>>k;
        for(int i=1;i<=k;i++)
        {
            cin>>w[i].beg>>w[i].dis;
            t[w[i].beg]++;
        }
        sort(w+1,w+k+1);
        int ji=1;
        for(int i=n;i>=1;i--)
        {
            if(!t[i])
                f[i]=f[i+1]+1;
            else
            {
                for(int j=1;j<=t[i];j++)
                {
                    if(f[i]<f[i+w[ji].dis])
                        f[i]=f[i+w[ji].dis];
                    ji++;
                }
            }
        }
        cout<<f[1];
        return 0;
    
    }
  • 相关阅读:
    最长公共子序列-动态规划
    归并排序
    最大子段和-3种方法
    kafka compaction 分析(基于kafka 0.10.2版本)
    [转载]interp1
    [转]mat2gray函数原理分析
    Java 位运算(移位、位与、或、异或、非)与逻辑运算
    ML01a
    [第1集] 机器学习的动机与应用
    tap4fun公司面试总结
  • 原文地址:https://www.cnblogs.com/olinr/p/9445618.html
Copyright © 2020-2023  润新知