HDU 4502 吉哥系列故事——临时工计划(一维动态规划)

题意:吉哥的假期是1到n天,然后有m个工作可以让吉哥选择做,每个工作都有一个开始 t_s  和结束的时间   t_e ,都用天来表示,然后每个工作必须从第一天做到最后一天,

从头到尾做完之后就可以得到C的报酬,现在要求吉哥这个假期最多能赚到多少钱?

解题报告:这个题就是一个典型的一维的动态规划,规划的公式是dp[i] = max(dp[i-(job[j].t_e-job[j].t_s+1)]+job[j].c,dp[i]);然后这题还有一个可以优化的地方,就是可

以将所有的工作先按照结束的时间从小到大排个序,这样的话,如果判断到循环到的那个工作的结束的时间比当前正在更新的时间晚的话,就可以退出这一层的循环,注意只是退

出一层循环,下面贴出优化前和优化后的两种不同代码以便于对比:

优化前代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 struct node
 8 {
 9     int t_s,t_e,c;
10 }job[1005];
11 int dp[105];
12 int main()
13 {
14     int T;
15     scanf("%d",&T);
16     while(T--)
17     {
18         int n,m;
19         scanf("%d%d",&n,&m);
20         for(int i = 0;i < m;++i)
21         scanf("%d%d%d",&job[i].t_s,&job[i].t_e,&job[i].c);
22         memset(dp,0,sizeof(dp));
23         int M = 0;
24         for(int i = 1;i <= n;++i)
25         for(int j = 0;j < m;++j)
26         if(job[j].t_e == i)
27         {
28             dp[i] = max(dp[i-(job[j].t_e-job[j].t_s+1)]+job[j].c,dp[i]);
29             M = max(M,dp[i]);
30         }
31         else dp[i] = max(dp[i],M);
32         printf("%d\n",dp[n]);
33     }
34     return 0;
35 }
View Code


优化代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 struct node
 8 {
 9     int t_s,t_e,c;
10     friend bool operator < (node a,node b)
11     {
12         return a.t_e < b.t_e;
13     }
14 }job[1005];
15 int dp[105];
16 int main()
17 {
18     int T;
19     scanf("%d",&T);
20     while(T--)
21     {
22         int n,m;
23         scanf("%d%d",&n,&m);
24         for(int i = 0;i < m;++i)
25         scanf("%d%d%d",&job[i].t_s,&job[i].t_e,&job[i].c);
26         sort(job,job+m);      //优化前的准备工作 
27         memset(dp,0,sizeof(dp));
28         int M = 0;
29         for(int i = 1;i <= n;++i)
30         for(int j = 0;j < m;++j)
31         {
32             if(job[j].t_e > i)       //一个优化,当这个工作的时间比当前正在更新的时间晚的话,就可以退出这层的循环 
33             break;                
34             if(job[j].t_e == i)
35             {
36                 dp[i] = max(dp[i-(job[j].t_e-job[j].t_s+1)]+job[j].c,dp[i]);
37                 M = max(M,dp[i]);
38             }
39             else dp[i] = max(dp[i],M);
40         }
41         printf("%d\n",dp[n]);
42     }
43     return 0;
44 }
View Code

 

转载于:https://www.cnblogs.com/xiaxiaosheng/p/3598828.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值