线性状态动态规划 P1280 尼克的任务【资源分配型动态规划】

题目

https://www.luogu.com.cn/problem/P1280

 

 题目分析

关于动态规划,求什么就设什么。所以设dp【i】为从0到i的空闲时间

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
    int start;
    int last;
}list[10002];
int dp[10002];
int sum[10002];
bool cmp(struct node&a,struct node &b)
{
    return a.start > b.start;
}
int  main()
{
    int n, k,num=1;
    scanf("%d%d", &n, &k);
    for (int i = 1; i <=k; i++)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        list[i].start = a; list[i].last = b;
        sum[a]++;//记录一个时间点有多少个任务
    }
    sort(list+1, list + k+1, cmp);
    for (int i = n; i > 0; i--)//本题要倒着推 及从大的时间往小的时间转移 因为 如果正着 在i的时候 显然还没转移 i+t
    {
        if (sum[i] == 0)//表示这个时间点是不是任何一个任务的开始节点,所以这个点的空闲时间就等于上个点的空闲时间加一
            dp[i] = dp[i + 1] + 1;
        else
            for (int j =1; j <=sum[i]; j++)//否则就从已经排好顺序的任务库list中取出一个事件
            {
                if (dp[i + list[num].last]>dp[i])//如果在此时间点开始的任务个数为1的话就直接dp[i] = dp[i + list[num].last];更新此时的dp【i】
                    dp[i] = dp[i + list[num].last];//但是如果有两个或以上任务,我们要进行任务的选择,使得dp【i】的值保持最小
                num++;//实现事件库的移动
            }
    }
    cout << dp[1] << endl;
}

 

posted @ 2020-06-14 19:33  Jason66661010  阅读(163)  评论(0编辑  收藏  举报