题解 尼克的任务

有一种和题解区完全不同的做法。

首先将所有任务按照时间从小到大排序,接着用 fi 表示处理前 i 个任务所能得到的最大空闲时间。

回顾一下需要满足的条件:再某个有任务的时刻,如果尼克是空闲的,就必须从中选择一个任务做。那么我们对于第 i 个任务,枚举上一个做的任务 j,必须满足的条件是:j 的结束时间 +1 i 的开始时间 1 没有其他任何事件。并且这样做的价值为 lenj+1i1

这样做的细节也颇多:由于第一个任务不一定是在时刻 1,所以我们得手动设置一个在时刻 0,长度为 1 的任务,同理需要在设置一个在时刻 k+1 的任务。

并且为了,满足所有 f 解出来都是合法的(即不会出现中间有空闲时间但是没做任务的情况),我们先将所有 f 设置为极小值,再令 f0=0 即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
inline LL read() {
LL sum=0,flag=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') flag=-1; c=getchar();}
while(c>='0'&&c<='9') {sum=sum*10+c-'0'; c=getchar();}
return sum*flag;
}
const int N=1e4+10;
int n,k;
int f[N];
struct node {
int p,t;
}a[N];
int cmp(node x,node y) {
return x.p<y.p;
}
int main() {
// freopen("a.in","r",stdin);
cin>>k>>n;
for(int i=1;i<=n;i++) cin>>a[i].p>>a[i].t;
sort(a+1,a+1+n,cmp);
a[n+1].p=k+1; a[0].t=1;
memset(f,-0x3f,sizeof(f));
f[0]=0;
for(int i=1;i<=n+1;i++) {
int lst=0;
for(int j=i-1;j>=0;j--) {
if(a[j].p+a[j].t-1<a[i].p) {
if(lst) {
if(a[j].p+a[j].t-1>=lst) {
f[i]=max(f[i],f[j]+max(a[i].p-(a[j].p+a[j].t),0));
}
}
else {
f[i]=max(f[i],f[j]+max(a[i].p-(a[j].p+a[j].t),0));
}
}
if(!lst&&a[j].p<a[i].p) lst=a[j].p;
}
}
cout<<f[n+1];
return 0;
}
posted @   2017BeiJiang  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示