码迷,mamicode.com
首页 > 其他好文 > 详细

P2577 [ZJOI2005]午餐

时间:2019-09-22 14:55:23      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:org   zjoi   ret   cpp   can   一个   需要   struct   clu   

题面:https://www.luogu.org/problem/P2577

本题一旦设出f[i][j]表示前i个人,在1号窗口打饭总时间j,最早吃完饭的时间
那么就很容易想到
当把i放在1号窗口
f[i][j] = min(f[i][j], max(f[i-1][j-s[i].a], j+s[i].b))
f[i-1][j-s[i].a]即第i个人吃饭+打饭时间<=前i-1人吃完饭的时间
j+s[i].b即第i个人吃饭+打饭时间>前i-1人吃完饭的时间
当把i放在2号窗口
f[i][j] = min(f[i][j], max(f[i-1][j], sum[i]-j+s[i].b));
注意这里需要维护一个前缀和,然后就可以用sum[i]-j表示在2号窗口打饭总时间了.

Code:
#include<bits/stdc++.h>
using namespace std;
const int N = 210;
int f[N][N*N];
struct node
{
    int a, b;
    bool operator <(node z) const
    {
        return b>z.b;
    }
}s[N];
int sum[N];
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d %d", &s[i].a, &s[i].b);
    sort(s+1, s+1+n);
    for(int i = 1; i <= n; i++)
        sum[i] = sum[i-1] + s[i].a;
    memset(f, 127, sizeof(f));
    f[0][0] = 0;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 0; j <= sum[i]; j++)
        {
            if(j>=s[i].a) f[i][j] = min(f[i][j], max(f[i-1][j-s[i].a], j+s[i].b));
            f[i][j] = min(f[i][j], max(f[i-1][j], sum[i]-j+s[i].b));
        }
    }
    int ans = 2147483647;
    for(int i = 0; i <= sum[n]; i++)
        ans = min(ans, f[n][i]);
    printf("%d\n", ans);
    return 0;
}

P2577 [ZJOI2005]午餐

标签:org   zjoi   ret   cpp   can   一个   需要   struct   clu   

原文地址:https://www.cnblogs.com/ukcxrtjr/p/11567180.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!