题目描述
尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成。
尼克的一个工作日为 𝑛n 分钟,从第 11 分钟开始到第 𝑛n 分钟结束。当尼克到达单位后他就开始干活,公司一共有 𝑘k 个任务需要完成。如果在同一时刻有多个任务需要完成,尼克可以任选其中的一个来做,而其余的则由他的同事完成,反之如果只有一个任务,则该任务必需由尼克去完成,假如某些任务开始时刻尼克正在工作,则这些任务也由尼克的同事完成。如果某任务于第 𝑝p 分钟开始,持续时间为 𝑡t 分钟,则该任务将在第 (𝑝+𝑡−1)(p+t−1) 分钟结束。
写一个程序计算尼克应该如何选取任务,才能获得最大的空暇时间。
输入格式
输入数据第一行含两个用空格隔开的整数 𝑛n 和 𝑘k。
接下来共有 𝑘k 行,每一行有两个用空格隔开的整数 𝑝p 和 𝑡t,表示该任务从第 𝑝p 分钟开始,持续时间为 𝑡t 分钟。
输出格式
输出文件仅一行,包含一个整数,表示尼克可能获得的最大空暇时间。
样例 #1
样例输入 #1
15 6
1 2
1 6
4 11
8 5
8 1
11 5
Copy
样例输出 #1
4
Copy
提示
数据规模与约定
- 对于 100%100% 的数据,保证 1≤𝑛≤104,1≤𝑘≤104,1≤𝑝≤𝑛,1≤𝑝+𝑡−1≤𝑛1≤n≤104,1≤k≤104,1≤p≤n,1≤p+t−1≤n。
0713Dp阶段练习
#include<bits/stdc++.h>
using namespace std;
long long kk,n,m=0,f[501][10001],c[10001],dfd=0,e[10001],je,pp=1,cn,ct=1;
long long boo[10001];
struct ll{
long long p,t,l;
}a[10001],b[1001][1001];
bool cmp(ll a,ll b){
return a.p<b.p;
}
int main(){
cin>>n>>kk;
memset(f,-1,sizeof(f));
for(int i=1;i<=kk;i++){
cin>>a[i].p>>a[i].t;
a[i].l=a[i].p+a[i].t-1;
}
// else{
sort(a+1,a+kk+1,cmp);
f[0][0]=0;
for(int i=1;i<=kk;i++){
if(a[i].p==a[pp].p){
for(int j=0;j<a[i].p;j++){
if(f[cn][j]>=0){
f[ct][a[i].l]=max(f[ct][a[i].l],f[cn][j]+a[i].p-j-1);
}
}
for(int j=a[i].p;j<=n;j++){
if(f[cn][j]>=0){
f[ct][j]=max(f[cn][j],f[ct][j]);
}
}
}
else{
for(int j=0;j<=n;j++){
//cout<<f[ct][j]<<" ";
f[cn][j]=-1;
}
//cout<<endl;
m=cn;
cn=ct;
ct=m;
pp=i;
i--;
}
}
for(int i=a[kk].p;i<=n;i++){
dfd=max(dfd,f[ct][i]+(n-i));
}
cout<<dfd;
// }
return 0;
}