没搞懂啊,这次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=Fstartj−1+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题吧少年……