码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4502吉哥系列故事——临时工计划 和 《尼克的任务》

时间:2014-06-02 10:12:26      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:des   c   style   class   blog   code   

bubuko.com,布布扣
吉哥系列故事——临时工计划

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
bubuko.com,布布扣

 

这道题有点像<尼克的任务>,比《尼克的任务》简单,对终止时间dp,得状态转移方程dp[j]=max{dp[j],dp[s[i]-1]+w[i]};

 

代码:

bubuko.com,布布扣
 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 }
bubuko.com,布布扣

顺便贴上尼克的任务:

bubuko.com,布布扣
尼克的任务【动态规划专项练习赛】——高级
Time Limit: 5000MS        Memory Limit: 65536K
Total Submissions: 29        Accepted: 17
Description

尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮件包含了尼克主管的部门当天要完成的全部任务,每个任务由一个开始时刻与一个持续时间构成。 

尼克的一个工作日为N分钟,从第一分钟开始到第N分钟结束。当尼克到达单位后他就开始干活。如果在同一时刻有多个任务需要完成,尼克可以任选其中的一个来做,而其余的则由他的同事完成,反之如果只有一个任务,则该任务必需由尼克去写成,假如某些任务开始时刻尼克正在工作,则这些任务也由尼克的同事完成。如果某任务于第P分钟开始,持续时间为T分钟,则该任务将在第P+T-1分钟结束。 

写一个程序计算尼克应该如何选取任务,才能获得最大的空暇时间。 
Input

输入数据第一行包含两个用空格隔开的整数N和K,1≤N≤100001≤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
bubuko.com,布布扣

这道题不容易想(我没想出来。。。),看了大神的代码,才知道这道题是倒推。。动态规划经常做正推的,实在是想不出来。。。

分析:

设dp[i]为从i-n时间段内最大空暇时间,那么如果第i分钟时没有任务,那么dp[i]=dp[i+1]+1;

如果第i分钟有或者有多个任务,设i分钟时有k个起始任务,那么dp[i]=max(dp[i],dp[i+T[i]]);

 

代码:

bubuko.com,布布扣
 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 }
bubuko.com,布布扣

 

 

HDU 4502吉哥系列故事——临时工计划 和 《尼克的任务》,布布扣,bubuko.com

HDU 4502吉哥系列故事——临时工计划 和 《尼克的任务》

标签:des   c   style   class   blog   code   

原文地址:http://www.cnblogs.com/qq1012662902/p/3763457.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!