CodeForces 158E Phone Talks dp

来源:互联网 发布:mac版的rar 解压软件 编辑:程序博客网 时间:2024/06/05 17:15

题解 : dp[i][j] 表示前 i 个选 j 个的最小需要的时间,
转移就是 dp[i][j] = min (dp[i - 1][j - 1],max(dp[i - 1][j] + a[i].d,a[i].t + a[i].d - 1));
剩下的暴力每一个数,看它和它前面的时间差有多少就可以了。

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>using namespace std;const int maxn = 4005;const int INF = 1e9 + 7;int n,k;struct node {    int t,d;}a[maxn];int dp[maxn][maxn] = {0};bool cmp (const node a,const node b) {    return a.t < b.t;}int main () {    ios_base :: sync_with_stdio(false);    cin >> n >> k;    for (int i = 1;i <= n; ++ i) {        cin >> a[i].t >> a[i].d;    }    a[0].t = 0;    a[n + 1].t = 86401;    if (n == k) {        cout << 86400 << endl;        return 0;    }    sort (a + 1,a + n + 1,cmp);    for (int i = 0;i < maxn; ++ i) {        for (int j = 0;j < maxn; ++ j) dp[i][j] = INF;    }    dp[0][0] = 0;    for (int i = 1;i <= n; ++ i) {        dp[i][0] = max (dp[i - 1][0],a[i].t - 1) + a[i].d;        for (int j = 1;j <= min(k,i); ++ j) {            dp[i][j] = min (dp[i - 1][j - 1],max(dp[i - 1][j] + a[i].d,a[i].t + a[i].d - 1));        }    }    int ans = a[1].t - 1;    for (int i = 1;i <= n; ++ i) {        int u = min (k,i);//        cout << dp[i][u] << endl;        ans = max (ans,a[i + 1].t - dp[i][u] - 1);    }    cout << ans << endl;    return 0;}