zoukankan      html  css  js  c++  java
  • 「题解」Codeforces 1348E Phoenix and Berries

    假如只把相同颜色的果子放在一起,会剩下 (sum amod k) 个红果子,(sum bmod k) 个绿果子,这是可以构造出来的答案的下界。

    剩下的红果子个数 (<k),蓝果子个数 (<k),果子和 (<2k),最多会凑出一个篮子,所以答案的上界是我们可以轻易构造出的下界 (+1)

    现在要判断这个上界是否能达到,我们可以假装全部相同颜色装在一起,然后拆篮子,通过在装同一棵树上的果子来消耗掉剩余的果子。

    (f_{i,j}) 代表考虑前 (i) 个树,消耗的红果子个数在模 (k) 意义下为 (j),那么消耗的蓝果子数就是 ((k-j)mod k),是否存在一种方案。

    (f_{i,j}=1,k-(sum b)mod kleq jleq (sum a)mod k),那么即存在一种方案可以拆开一些篮子然后消耗掉剩余的果子来达到答案的上界。

    直接 dp 的复杂度为 (mathcal{O}(nk^2)),可以前缀和优化优化到 (mathcal{O}(nk))

    #include<iostream>
    #include<cstdio>
    typedef long long ll;
    template <typename T> T Max(T x, T y) { return x > y ? x : y; }
    template <typename T> T Min(T x, T y) { return x < y ? x : y; }
    template <typename T>
    T &read(T &r) {
    	r = 0; bool w = 0; char ch = getchar();
    	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    	while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
    	return r = w ? -r : r;
    }
    int Mod(int x, int y) { return x < 0 ? (x + y) : (x >= y ? (x - y) : x); }
    const int N = 510;
    int n, k;
    int a[N], b[N];
    ll sa, sb, ans, f[N], g[N];
    int Sum(int l, int r) {
    	if(l <= r) return g[r] - (l == 0 ? 0 : g[l-1]);
    	return g[r] + g[k-1] - g[l-1];
    }
    signed main() {
    	read(n); read(k);
    	for(int i = 1; i <= n; ++i) read(a[i]), read(b[i]), sa += a[i], sb += b[i];
    	ans = sa / k + sb / k; sa %= k, sb %= k;
    	if(sa + sb < k) {
    		printf("%lld
    ", ans);
    		return 0;
    	}
    	f[0] = 1;
    	for(int i = 1; i <= n; ++i) {
    		for(int j = 0; j < k; ++j) g[j] = f[j];
    		for(int j = 1; j < k; ++j) g[j] += g[j-1];
    		for(int j = 0; j < k; ++j) 
    			if(!f[j]) {
    				int L = j-Min(a[i], k-1), R = j-Max(0, k-b[i]);
    				if(L > R) continue ;
    				L = Mod(L, k); R = Mod(R, k);
    				if(Sum(L, R)) f[j] = 1;
    			}
    		for(int j = k - sb; j <= sa; ++j)
    			if(f[j]) {
    				printf("%lld
    ", ans+1);
    				return 0;
    			}
    	}
    	printf("%lld
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    HDU2586 How far away?(tarjan的LCA)
    You Raise Me Up
    POJ2891 Strange Way to Express Integers(中国剩余定理)
    POJ2142 The Balance(扩展欧几里得)
    HDU 1166模仿大牛写的线段树
    NetWord Dinic
    HDU 1754 线段树裸题
    hdu1394 Minimum Inversion Number
    hdu2795 Billboard
    【完全版】线段树
  • 原文地址:https://www.cnblogs.com/do-while-true/p/15321799.html
Copyright © 2011-2022 走看看