zoukankan      html  css  js  c++  java
  • 洛谷P2577 [ZJOI2005]午餐

    挺棒的一道dp。

    贪心策略容易想到。直接按吃饭时间从大到小排序即可。

    重点是dp。可以设方程为 f[前 i 人] [ 队列1的时间 j ] 然后加上一个常见的滚动数组套路。

    方程的转移还是很有意思。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int MAXN = 200 + 10;
    
    struct People
    {
        int a, b;
        bool operator >(const People &rhs) const{
            return b > rhs.b;
        }
    }pe[MAXN];
    
    int N;
    int f[2][MAXN * MAXN];
    int sum[MAXN];
    
    int main()
    {   
        cin>>N;
        for(int i = 1; i <= N; i++)
            scanf("%d%d", &pe[i].a, &pe[i].b);
        sort(pe + 1, pe + N + 1, greater<People>());
        for(int i = 1; i <= N; i++) sum[i] = sum[i - 1] + pe[i].a;
        memset(f, 0x3f, sizeof(f)); 
    
        int tmp = 0, d = 0; f[d][0] = 0;
        for(int i = 1; i <= N; i++){
            d ^= 1; memset(f[d], 0x3f, sizeof(f[d]));
            for(int j = 0; j <= tmp; j++){
                f[d][j + pe[i].a] = min(f[d][j + pe[i].a], max(f[d ^ 1][j], j + pe[i].a + pe[i].b));
                f[d][j] = min(f[d][j], max(f[d ^ 1][j], sum[i] - j + pe[i].b));
            }
            tmp += pe[i].a;
        }
        
        int ans = (1 << 29);
        for(int i = 0; i <= tmp; i++) ans = min(ans, f[d][i]);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    [BJOI2006]狼抓兔子
    [HNOI2016]最小公倍数
    hihocoder 1419 重复旋律4
    [NOI2015]品酒大会
    [SDOI2016]生成魔咒
    [ZJOI2009]狼和羊的故事
    BZOJ4361 isn
    [SDOI2009]虔诚的墓主人
    BZOJ 3329 Xorequ
    [ZJOI2013]丽洁体
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/9319912.html
Copyright © 2011-2022 走看看