zoukankan      html  css  js  c++  java
  • 洛谷P1280 尼克的任务

    P1280 尼克的任务

    题目描述

    尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成。

    尼克的一个工作日为N分钟,从第一分钟开始到第N分钟结束。当尼克到达单位后他就开始干活。如果在同一时刻有多个任务需要完戍,尼克可以任选其中的一个来做,而其余的则由他的同事完成,反之如果只有一个任务,则该任务必需由尼克去完成,假如某些任务开始时刻尼克正在工作,则这些任务也由尼克的同事完成。如果某任务于第P分钟开始,持续时间为T分钟,则该任务将在第P+T-1分钟结束。

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

    输入输出格式

    输入格式:

    输入数据第一行含两个用空格隔开的整数N和K(1≤N≤10000,1≤K≤10000),N表示尼克的工作时间,单位为分钟,K表示任务总数。

    接下来共有K行,每一行有两个用空格隔开的整数P和T,表示该任务从第P分钟开始,持续时间为T分钟,其中1≤P≤N,1≤P+T-1≤N。

    输出格式:

    输出文件仅一行,包含一个整数,表示尼克可能获得的最大空暇时间。

    输入输出样例

    输入样例#1:
    15 6
    1 2
    1 6
    4 11
    8 5
    8 1
    11 5
    
    输出样例#1:
    4
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define maxn 10010
    using namespace std;
    int N,n,ans;
    struct node{
        int l,r,nxt;
        bool operator < (const node b)const{
            if(l!=b.l)return l<b.l;
            return r<b.r;
        }
    }a[maxn];
    void dfs(int now,int sum){
        if(a[now].nxt==0){
            ans=max(ans,sum+(N-a[now].r));
            return;
        }
        int left=a[a[now].nxt].l;
        int add=left-a[now].r;
        for(int i=a[now].nxt;i<=n;i++){
            if(a[i].l>left)break;
            dfs(i,sum+add);
        }
    }
    int main(){
        freopen("Cola.txt","r",stdin);
        scanf("%d%d",&N,&n);
        int x,y;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&x,&y);
            a[i].l=x-1;a[i].r=x+y-1;
        }
        sort(a+1,a+n+1);
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                if(a[j].l>a[i].r){a[i].nxt=j;break;}
        int s=a[1].l;
        for(int i=1;i<=n;i++){
            if(a[i].l==s)dfs(i,0);
            else break;
        }
        ans+=s;
        printf("%d",ans);
    }
    10分 暴力 不知道为什么WA了两个点
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define maxn 10010
    using namespace std;
    int n,k,f[maxn];
    struct node{
        int l,r,nxt;
        bool operator < (const node b)const{
            return l<b.l;
        }
    }a[maxn];
    int search(int cur){
        if(f[cur])return f[cur];
        int res=0x7fffffff,limit=0x7fffffff;
        for(int i=cur+1;i<=k;i++){
            if(a[i].l>limit)break;
            else if(a[i].l>a[cur].r){
                res=min(res,search(i));
                limit=min(limit,a[i].l);
            }
        }
        f[cur]=a[cur].r-a[cur].l+1;
        if(res!=0x7fffffff)return f[cur]+=res;
        else return f[cur];
    }
    int main(){
        scanf("%d%d",&n,&k);
        a[0].l=1;a[0].r=0;
        for(int i=1;i<=k;i++)scanf("%d%d",&a[i].l,&a[i].r),a[i].r+=a[i].l-1;
        sort(a+1,a+k+1);
        search(0);
        printf("%d",n-f[0]);
        return 0;
    }
    100分 记忆化搜索
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    #define maxn 10010
    int n,k,sum[maxn],num=1,f[maxn];
    struct node{
        int l,r;
        bool operator < (const node b)const{
            return l>b.l;
        }
    }a[maxn];
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=k;i++){
            scanf("%d%d",&a[i].l,&a[i].r);
            sum[a[i].l]++;
        }
        sort(a+1,a+k+1);
        for(int i=n;i>=1;i--)
            if(sum[i]==0)f[i]=f[i+1]+1;
            else for(int j=1;j<=sum[i];j++){
                f[i]=max(f[i],f[i+a[num].r]);
                num++;
            }
        printf("%d",f[1]);
    }
    100分 递推
  • 相关阅读:
    基础总结深入:数据类型的分类和判断(数据、内存、变量) 对象 函数 回调函数 IIFE 函数中的this 分号
    BOM 定时器 通过修改元素的类来改变css JSON
    事件 事件的冒泡 事件的委派 事件的绑定 事件的传播
    DOM修改 使用DOM操作CSS
    包装类 Date Math 字符串的相关的方法 正则表达式 DOM DOM查询
    数组 call()、apply()、bind()的使用 this arguments
    autocad 二次开发 最小包围圆算法
    win10 objectarx向导在 vs2015中不起作用的解决办法
    AutoCad 二次开发 jig操作之标注跟随线移动
    AutoCad 二次开发 文字镜像
  • 原文地址:https://www.cnblogs.com/thmyl/p/7661735.html
Copyright © 2011-2022 走看看