线性状态动态规划 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; }