LuoguP1280尼克的任务 : 线性dp
题目描述
尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成。
尼克的一个工作日为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。
输出格式:
输出文件仅一行,包含一个整数,表示尼克可能获得的最大空暇时间。
INPUT & OUTPUT‘s examples
Input‘s e.g. #1
15 6 1 2 1 6 4 11 8 5 8 1 11 5
Output‘s e.g. #
4
分析
比较简单的一道线性dp题目。
我们采用逆推的方式,设 dp[i] 表示从后往前推到 i的最大空闲时间。
首先,如果第i个时刻没有工作,那么就直接 dp[i] = dp[i+1] + 1 即可(直接算上)
然后,如果有工作,那么我们就要选一个在任务结束后空闲时间最大的任务,那么显然可以得出:
dp[i] = std::max(dp[i+Time[i][j])
这里我们用一个动态数组 std::vector<int> v[MAXN] 来储存时刻 i开始的任务持续时间。
代码
1 /* Headers */ 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<cctype> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #include<stack> 10 #include<climits> 11 #include<iostream> 12 #include<map> 13 #define FOR(i,a,b,c) for(int i=(a);i<=(b);i+=(c)) 14 #define ROF(i,a,b,c) for(int i=(a);i>=(b);i-=(c)) 15 #define FORL(i,a,b,c) for(long long i=(a);i<=(b);i+=(c)) 16 #define ROFL(i,a,b,c) for(long long i=(a);i>=(b);i-=(c)) 17 #define FORR(i,a,b,c) for(register int i=(a);i<=(b);i+=(c)) 18 #define ROFR(i,a,b,c) for(register int i=(a);i>=(b);i-=(c)) 19 #define lowbit(x) x&(-x) 20 #define LeftChild(x) x<<1 21 #define RightChild(x) (x<<1)+1 22 #define RevEdge(x) x^1 23 #define FILE_IN(x) freopen(x,"r",stdin); 24 #define FILE_OUT(x) freopen(x,"w",stdout); 25 #define CLOSE_IN() fclose(stdin); 26 #define CLOSE_OUT() fclose(stdout); 27 #define IOS(x) std::ios::sync_with_stdio(x) 28 #define Dividing() printf("-----------------------------------\n"); 29 namespace FastIO{ 30 const int BUFSIZE = 1 << 20; 31 char ibuf[BUFSIZE],*is = ibuf,*its = ibuf; 32 char obuf[BUFSIZE],*os = obuf,*ot = obuf + BUFSIZE; 33 inline char getch(){ 34 if(is == its) 35 its = (is = ibuf)+fread(ibuf,1,BUFSIZE,stdin); 36 return (is == its)?EOF:*is++; 37 } 38 inline int getint(){ 39 int res = 0,neg = 0,ch = getch(); 40 while(!(isdigit(ch) || ch == ‘-‘) && ch != EOF) 41 ch = getch(); 42 if(ch == ‘-‘){ 43 neg = 1;ch = getch(); 44 } 45 while(isdigit(ch)){ 46 res = (res << 3) + (res << 1)+ (ch - ‘0‘); 47 ch = getch(); 48 } 49 return neg?-res:res; 50 } 51 inline void flush(){ 52 fwrite(obuf,1,os-obuf,stdout); 53 os = obuf; 54 } 55 inline void putch(char ch){ 56 *os++ = ch; 57 if(os == ot) flush(); 58 } 59 inline void putint(int res){ 60 static char q[10]; 61 if(res==0) putch(‘0‘); 62 else if(res < 0){putch(‘-‘);res = -res;} 63 int top = 0; 64 while(res){ 65 q[top++] = res % 10 + ‘0‘; 66 res /= 10; 67 } 68 while(top--) putch(q[top]); 69 } 70 inline void space(bool x){ 71 if(!x) putch(‘\n‘); 72 else putch(‘ ‘); 73 } 74 } 75 inline void read(int &x){ 76 int rt = FastIO::getint(); 77 x = rt; 78 } 79 inline void print(int x,bool enter){ 80 FastIO::putint(x); 81 FastIO::flush(); 82 FastIO::space(enter); 83 } 84 /* definitions */ 85 const int MAXN = 1e4 + 10; 86 int n,k; 87 int dp[MAXN]; 88 std::vector<int> Time[MAXN]; 89 /* functions */ 90 int main(int argc,char *argv[]){ 91 scanf("%d%d",&n,&k); 92 FOR(i,1,k,1){ 93 int p,t; 94 scanf("%d%d",&p,&t); 95 Time[p].push_back(t); 96 } 97 ROF(i,n,1,1){ 98 if(Time[i].size() > 0) 99 FOR(j,0,Time[i].size()-1,1) 100 dp[i] = std::max(dp[i],dp[i+Time[i][j]]); 101 else dp[i] = dp[i + 1] + 1; 102 } 103 printf("%d\n",dp[1]); 104 return 0; 105 }
Luogu1280
原文地址:https://www.cnblogs.com/herself32-lyoi/p/10783570.html
时间: 2024-10-11 10:39:26