• BZOJ1899 [Zjoi2004]Lunch 午餐 贪心+DP


    题目传送门

    https://lydsy.com/JudgeOnline/problem.php?id=1899

    题解

    如果只有一个窗口,那么可以这样考虑:因为最后一个人打完饭的时间是固定的,那么不如就让吃饭最快的人最后打完。然后以此类推到前 (n-1) 个人……最终可以得出把所有的人的吃饭时间倒序排序以后打饭最优。

    但是,如果有两个窗口,那么一开始的大前提“最后一个人打完饭的时间是固定的”就不对了。(为了想为什么两个窗口就不对想了两节课)

    不过我们可以发现,如果把两个窗口单独考虑,各自也还应该是按吃饭时间倒序排序的。因此我们可以先把所有人按照吃饭时间倒序排序以后来分配窗口。

    我们发现对于第 (i) 个人,只需要知道前 (i-1) 个人中,在其中一个窗口打饭的总时间就可以算出当前的第 (i) 个人在每个窗口打饭时最终所需的时间。

    因此考虑 dp,令 (dp[i][j]) 表示前 (i) 个人中在第一个窗口打饭的总时间为 (j) 时,前 (i) 个人吃完饭的最大的时间。

    #include<bits/stdc++.h>
    
    #define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
    #define dbg(...) fprintf(stderr, __VA_ARGS__)
    #define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
    #define fi first
    #define se second
    #define pb push_back
    
    template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
    template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}
    
    typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;
    
    template<typename I>
    inline void read(I &x) {
    	int f = 0, c;
    	while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    	x = c & 15;
    	while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    	f ? x = -x : 0;
    }
    
    const int N = 200 + 7;
    const int M = 200 * 200 + 7;
    
    int n;
    int s[N], dp[N][M];
    
    struct Wph { int a, b; } a[N];
    inline bool operator < (const Wph &p, const Wph &q) { return p.b > q.b; }
    
    inline void work() {
    	for (int i = 1; i <= n; ++i) s[i] = s[i - 1] + a[i].a;
    	memset(dp, 0x3f, sizeof(dp)), dp[0][0] = 0;
    	for (int i = 1; i <= n; ++i) {
    		for (int j = 0; j <= s[i]; ++j) {
    			dp[i][j] = std::max(dp[i - 1][j], s[i] - j + a[i].b);
    			if (j >= a[i].a) smin(dp[i][j], std::max(dp[i - 1][j - a[i].a], j + a[i].b));
    		}
    	}
    	int ans = s[n] + a[n].b;
    	for (int i = 0; i <= s[n]; ++i) smin(ans, dp[n][i]);
    	printf("%d
    ", ans);
    }
    
    inline void init() {
    	read(n);
    	for (int i = 1; i <= n; ++i) read(a[i].a), read(a[i].b);
    	std::sort(a + 1, a + n + 1);
    }
    
    int main() {
    #ifdef hzhkk
    	freopen("hkk.in", "r", stdin);
    #endif
    	init();
    	work();
    	fclose(stdin), fclose(stdout);
    	return 0;
    }
    
    
  • 相关阅读:
    django-rest-framework
    史上最全的状态码
    __new__、__init__、__call__三个特殊方法
    量化投资与Python之pandas
    MongoDB 3.0 Release Notes
    TokuMX写操作无法加锁的问题
    TokuMX唯一索引不支持dropDups选项
    接着写吧
    Windows下Python IDLE设置
    20145320周岐浩免考
  • 原文地址:https://www.cnblogs.com/hankeke/p/BZOJ1899.html
Copyright © 2020-2023  润新知