【CodeForces 158E】Phone Talks(DP)

来源:互联网 发布:化工控制软件 编辑:程序博客网 时间:2024/06/05 16:25

题意很好理解,这里就不再赘述了。

这道题以dp[i][j]表示前i个物品在放弃j个时能取的最小的时间,然后状态转移就是:

不选这个任务时:dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j]);选择这个任务时:if(st > dp[i][j])//如果这个任务开始时间比dp[i][j]迟{    dp[i + 1][j] = min(dp[i + 1][j], st + dur - 1);    ans = max(ans, st - dp[i][j] - 1);}else dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + dur);

知道这个状态转移还不足以解决这道题:

1.忽略了n = 0 或者n = k时,最长的时间就是86400

2.可能选完n个任务后,时间还没有达到86400,还有剩余的时间


AC代码:

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;const int INF = 0x3f3f3f3f;int dp[4005][4005];struct node{    int st, dur;}nodes[4005];int main(){    int n, k;    scanf("%d%d", &n, &k);    if(n == 0 ||  k == n)    {        printf("86400\n");        return 0;    }    for(int i = 0; i < n; ++i)        scanf("%d%d", &nodes[i].st, &nodes[i].dur);    for(int i = 0; i <= n; ++i)        for(int j = 0; j <= k; ++j)        dp[i][j] = INF;    dp[0][0] = 0;    int ans = 0;    for(int i = 0; i < n; ++i)    {        for(int j = 0; j <= k; ++j)        {            if(dp[i][j] != INF)            {                dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j]);                int st = nodes[i].st;                int dur = nodes[i].dur;                if(st > dp[i][j])                {                    dp[i + 1][j] = min(dp[i + 1][j], st + dur - 1);                    ans = max(ans, st - dp[i][j] - 1);                }                else dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + dur);            }        }    }    //可能选完n个任务后,时间还没有达到86400,还有剩余的时间    for(int j = 0; j <= k; ++j)    {        ans = max(ans, 86400 - dp[n][j]);    }    printf("%d\n", ans);    return 0;}


原创粉丝点击