P1280 尼克的任务
好丢脸啊!普及dp都做不出来!
这道题应该要倒推来做dp。
别人说顺推也可以,但我又不会刷表啊!刚才刷了一遍全部WA。
那我们就乖乖地倒推。
我一开始想定义状态的时候就错了。只需要定义\(dp[i]\)一维就可以了,因为这些任务一定会被做。
我们考虑的有两种决策:
-
这一分钟没有新任务的开始。那我们就歇着。
-
这一分钟有新任务开始。那么我们应该遍历所有有关的这些任务,从未来的时间状态一步转移过来。
发现这些任务可能是乱的,所以我们可以排序。
很重要的一点:定义一个num变量,表示当前已经做了num个任务。
然后我们就按照递推思路写dp即可。详情看代码:
#include<cstdio>
#include<algorithm>
const int maxn = 10005;
struct Nodes
{
int p, t;
} s[maxn];
int dp[maxn];
int sum[maxn];
int num = 1;//
int n, m;
bool cmp(const Nodes a, const Nodes b)
{
return a.p > b.p;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
{
scanf("%d%d", &s[i].p, &s[i].t);
sum[s[i].p]++;
}
std::sort(s + 1, s + 1 + m, cmp);
for(int i = n; i >= 1; i--)
{
if(sum[i] == 0) dp[i] = dp[i + 1] + 1;
else
{
for(int j = 1; j <= sum[i]; j++)
{
dp[i] = std::max(dp[i], dp[i + s[num].t]);
num++;
}
}
}
printf("%d\n", dp[1]);
return 0;
}