标签:des c style class blog code
吉哥系列故事——临时工计划 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 2794 Accepted Submission(s): 1081 Problem Description 俗话说一分钱难倒英雄汉,高中几年下来,吉哥已经深深明白了这个道理,因此,新年开始存储一年的个人资金已经成了习惯,不过自从大学之后他不好意思再向大人要压岁钱了,只能把唯一的希望放到自己身上。可是由于时间段的特殊性和自己能力的因素,只能找到些零零碎碎的工作,吉哥想知道怎么安排自己的假期才能获得最多的工资。 已知吉哥一共有m天的假期,每天的编号从1到m,一共有n份可以做的工作,每份工作都知道起始时间s,终止时间e和对应的工资c,每份工作的起始和终止时间以天为单位(即天数编号),每份工作必须从起始时间做到终止时间才能得到总工资c,且不能存在时间重叠的工作。比如,第1天起始第2天结束的工作不能和第2天起始,第4天结束的工作一起被选定,因为第2天吉哥只能在一个地方工作。 现在,吉哥想知道怎么安排才能在假期的m天内获得最大的工资数(第m+1天吉哥必须返回学校,m天以后起始或终止的工作是不能完成的)。 Input 第一行是数据的组数T;每组数据的第一行是2个正整数:假期时间m和可做的工作数n;接下来n行分别有3个正整数描述对应的n个工作的起始时间s,终止时间e,总工资c。 [Technical Specification] 1<=T<=1000 9<m<=100 0<n<=1000 s<=100, e<=100, s<=e c<=10000 Output 对于每组数据,输出吉哥可获得的最高工资数。 Sample Input 1 10 5 1 5 100 3 10 10 5 10 100 1 4 2 6 12 266 Sample Output 102
这道题有点像<尼克的任务>,比《尼克的任务》简单,对终止时间dp,得状态转移方程dp[j]=max{dp[j],dp[s[i]-1]+w[i]};
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <iostream> 5 using namespace std; 6 7 struct mem{ 8 int s, e, w; 9 }a[1005]; 10 11 bool cmp(mem a,mem b) 12 { 13 return a.e<b.e; 14 } 15 main() 16 { 17 int n, i, j, k, t, x, y, z, m, dp[110]; 18 cin>>t; 19 while(t--) 20 { 21 cin>>m>>n; 22 k=0; 23 for(i=0;i<n;i++) 24 { 25 scanf("%d %d %d",&x,&y,&z); 26 if(x<1||x>m||y>m) continue; 27 a[k].s=x; 28 a[k].e=y; 29 a[k++].w=z; 30 } 31 sort(a,a+k,cmp); 32 memset(dp,0,sizeof(dp)); 33 for(i=0;i<k;i++) 34 { 35 for(j=m;j>=a[i].e;j--) 36 dp[j]=max(dp[j],dp[a[i].s-1]+a[i].w); 37 } 38 printf("%d\n",dp[m]); 39 } 40 }
顺便贴上尼克的任务:
尼克的任务【动态规划专项练习赛】——高级 Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 29 Accepted: 17 Description 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成。 尼克的一个工作日为N分钟,从第一分钟开始到第N分钟结束。当尼克到达单位后他就开始干活。如果在同一时刻有多个任务需要完成,尼克可以任选其中的一个来做,而其余的则由他的同事完成,反之如果只有一个任务,则该任务必需由尼克去写成,假如某些任务开始时刻尼克正在工作,则这些任务也由尼克的同事完成。如果某任务于第P分钟开始,持续时间为T分钟,则该任务将在第P+T-1分钟结束。 写一个程序计算尼克应该如何选取任务,才能获得最大的空暇时间。 Input 输入数据第一行包含两个用空格隔开的整数N和K,1≤N≤10000,1≤K≤10000,N表示尼克的工作时间,单位为分,K表示任务总数。 接下来共有K行,每一行有两个用空格隔开的整数P和T,表示该任务从第P分钟开始,持续时间为T分钟,其中1≤P≤N,1≤P+T-1≤N。 Output 输出文件仅一行包含一个整数表示尼克可能获得的最大空暇时间。 Sample Input 15 6 1 2 1 6 4 11 8 5 8 1 11 5 Sample Output 4
这道题不容易想(我没想出来。。。),看了大神的代码,才知道这道题是倒推。。动态规划经常做正推的,实在是想不出来。。。
分析:
设dp[i]为从i-n时间段内最大空暇时间,那么如果第i分钟时没有任务,那么dp[i]=dp[i+1]+1;
如果第i分钟有或者有多个任务,设i分钟时有k个起始任务,那么dp[i]=max(dp[i],dp[i+T[i]]);
代码:
1 #include <stdio.h> 2 #include <iostream> 3 #include <algorithm> 4 #include <string.h> 5 #include <vector> 6 using namespace std; 7 8 main() 9 { 10 vector<int>time[10005]; 11 int n, k, i, j, a, b, dp[10005]; 12 scanf("%d %d",&n,&k); 13 for(i=1;i<=k;i++) 14 { 15 scanf("%d %d",&a,&b); 16 time[a].push_back(b); 17 } 18 memset(dp,0,sizeof(dp)); 19 for(i=n;i>=1;i--) 20 { 21 if(time[i].empty()) 22 dp[i]=dp[i+1]+1; 23 else { 24 for(j=0;j<time[i].size();j++) 25 dp[i]=max(dp[i],dp[i+time[i][j]]); 26 } 27 } 28 printf("%d\n",dp[1]); 29 }
HDU 4502吉哥系列故事——临时工计划 和 《尼克的任务》,布布扣,bubuko.com
HDU 4502吉哥系列故事——临时工计划 和 《尼克的任务》
标签:des c style class blog code
原文地址:http://www.cnblogs.com/qq1012662902/p/3763457.html