临时工计划

18 篇文章 0 订阅

没搞懂啊,这次XC开始在T2+DP了呢。
咋肥四呢,不管了,先看看题先。

概括一下题目大意:一个人要去打工,然后他有m天的时间和n分临时工。现在输入每次工作的起始天和结束天,包括可以获得的工资。要算最多可以拿多少工资。(9<m<=100,0<n<=1000)
先想一下主要思路,我们可以看出这道题的数据还是很小的。所以果断想是DP或者是贪心。发现每一次选择没有后效性后,我们先来试一试DP。

F i F_{i} Fi为第i天可以拿到最多的工资,那么我们现在可以确定第一个循环,就是1-m枚举天数了。显而易见,第二个循环就应该是每一个工作的枚举,也就是1-n

状态转移方程,由于 f i f_{i} fi是当前天的最大工资,所以我们考虑之前的工作选择。那就是那个工作的起始时间前一天的最大价值+工资了。
F i = F s t a r t j − 1 + c j F_i=F_{start_{j-1}}+c_{j} Fi=Fstartj1+cj

然后你发现,惊喜的连样例都过不了。
所以你开始思考什么,这样例最后输出是多了的,说明是选工作有问题。那我们还有什么没用上呢?
好似忘记结束天 e n d j end_{j} endj了是吧,那怎么加上它特判呢?
我们是不是要看看这个工作的结束天有没有超过所枚举的i呢?那就是:if( e n d j end_{j} endj<=i) 。试一试,嗯?正解?

然后交上去,AC了呢。

#include<cstdio>
#include<cstring>
using namespace std;
int n,m;
int s[1005],e[1005],p[1005],f[1005];
int max(int a,int b)
{
	if(a>b) return a;
	else return b;
}
int main()
{
	freopen("partime.in","r",stdin);
	freopen("partime.out","w",stdout);
    memset(f,0,sizeof(f));
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;++i) scanf("%d%d%d",&s[i],&e[i],&p[i]);
    for(int i=1;i<=m;++i)
        for(int j=1;j<=n;++j)
            if(e[j]<=i)
                f[i]=max(f[i],f[s[j]-1]+p[j]);
    printf("%d",f[m]);
    return 0;
}

多练DP题吧少年……

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值