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;
}
posted @ 2018-08-13 18:04  Garen-Wang  阅读(120)  评论(0编辑  收藏  举报