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


吉哥系列故事——临时工计划

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吉哥系列故事——临时工计划 和 《尼克的任务》

时间: 2024-09-27 09:40:55

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

hdu 4502 吉哥系列故事——临时工计划

吉哥系列故事--临时工计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 2921    Accepted Submission(s): 1128 Problem Description 俗话说一分钱难倒英雄汉,高中几年下来,吉哥已经深深明白了这个道理,因此,新年开始存储一年的个人资金已经成了习惯,不过自从大学之后他不好意思再向大人要

HDU 4502 吉哥系列故事——临时工计划(DP)

Problem Description 俗话说一分钱难倒英雄汉,高中几年下来,吉哥已经深深明白了这个道理,因此,新年开始存储一年的个人资金已经成了习惯,不过自从大学之后他不好意思再向大人要压岁钱了,只能把唯一的希望放到自己身上.可是由于时间段的特殊性和自己能力的因素,只能找到些零零碎碎的工作,吉哥想知道怎么安排自己的假期才能获得最多的工资. 已知吉哥一共有m天的假期,每天的编号从1到m,一共有n份可以做的工作,每份工作都知道起始时间s,终止时间e和对应的工资c,每份工作的起始和终止时间以天为单位

hdu 4502吉哥系列故事——临时工计划 (简单DP)

Problem Description 俗话说一分钱难倒英雄汉,高中几年下来,吉哥已经深深明白了这个道理,因此,新年开始存储一年的个人资金已经成了习惯,不过自从大学之后他不好意思再向大人要压岁钱了,只能把唯一的希望放到自己身上.可是由于时间段的特殊性和自己能力的因素,只能找到些零零碎碎的工作,吉哥想知道怎么安排自己的假期才能获得最多的工资. 已知吉哥一共有m天的假期,每天的编号从1到m,一共有n份可以做的工作,每份工作都知道起始时间s,终止时间e和对应的工资c,每份工作的起始和终止时间以天为单位

HDU ACM 4502 吉哥系列故事——临时工计划 -&gt;动态规划

分析:dp[i]表示前i天的最大收入. 现排序,然后dp[i]=max(dp[i],dp[a[j].s-1]+a[j].v)(a[j].e<=i). #include<iostream> #include<algorithm> using namespace std; #define N 110 int dp[N]; //dp[i]表示第i天的最大收入 struct Node { int s,e,v; } node[N*10]; bool cmp(const Node&

吉哥系列故事——临时工计划(dp)

吉哥系列故事——临时工计划 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 3046 Accepted Submission(s): 1197 Problem Description 俗话说一分钱难倒英雄汉,高中几年下来,吉哥已经深深明白了这个道理,因此,新年开始存储一年的个人资金已经成了习惯,不过自从大学之后他不好意思再向大人要压岁钱了,只能

HDU 4513 吉哥系列故事——完美队形II(Manacher)

Problem Description 吉哥又想出了一个新的完美队形游戏! 假设有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成一个新的队形,新的队形若满足以下三点要求,则就是新的完美队形: 1.挑出的人保持原队形的相对顺序不变,且必须都是在原队形中连续的: 2.左右对称,假设有m个人形成新的队形,则第1个人和第m个人身高相同,第2个人和第m-1个人身高相同,依此类推,当然如果m是奇数,中间那个人可以任意: 3.从左到中间那

HDU 4512 吉哥系列故事——完美队形(LCIS)

Problem Description 吉哥这几天对队形比较感兴趣. 有一天,有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成一个新的队形,新的队形若满足以下三点要求,则称之为完美队形: 1.挑出的人保持他们在原队形的相对顺序不变: 2.左右对称,假设有m个人形成新的队形,则第1个人和第m个人身高相同,第2个人和第m-1个人身高相同,依此类推,当然,如果m是奇数,中间那个人可以任意: 3.从左到中间那个人,身高需保证递增,如

Hdu 4507 吉哥系列故事——恨7不成妻 (数位DP)

题目链接: Hdu 4507 吉哥系列故事——恨7不成妻 题目描述: 中文题面不描述. 解题思路: 从数据范围可看出是数位DP.根据题目给的限制,如果是求满足限制的数的数目的话,就很简单了.但是这个题目是让求满足题目中限制的数的平方和.我们可以求出区间中满足题目中限制的数的数目,和这些数的和,然后从这两个东西推出这些数的平方和. 假设现在我们已经递归出后面的x-1位满足题目限制的数的数目(num),和(sum),平方和(ssum),当前x位枚举为i,就可以推出当前节点改变为Num += num,

HDU 4513 吉哥系列故事——完美队形II manacher求最长回文

题目来源:吉哥系列故事--完美队形II 题意:中文 思路:在manacher算法向两边扩展的时候加判断 保证非严格递减就行了 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100110; int a[maxn<<1]; int b[maxn<<1]; int dp[maxn<<1]; int