zoukankan      html  css  js  c++  java
  • LOJ #2392. 「JOISC 2017 Day 1」烟花棒(贪心)

    https://loj.ac/problem/2392

    第一步二分答案。

    注意其它人也是可以移动的,且其它人肯定往中间靠拢。

    考虑不可能两个人同时拿着烟花跑,一个人跑(这个人跑完后再用新的烟花跑是一样的)是更优的,所以遇到一个人相当于时间加T。

    问题变为:
    有两个队列,每个队列有一些数,你需要从左往右选数,满足当前的时间一直(ge 0),问是否可行。

    和这题类似:
    http://www.lydsy.com/JudgeOnline/problem.php?id=3709

    考虑如果选了一个负数,那么就要一直选直到和(ge 0),不然就不会选这个负数。

    把每个队列缩成若干((x,y)(yge 0)):进来前要(ge x),出去后加了(y),注意会剩下一些不能缩的。

    先看,能不能把二元组做完,对于剩下的,考虑先加上它们,再倒过来做,问题等价。

    Code:

    #include<bits/stdc++.h>
    #define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
    #define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
    #define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
    #define ll long long
    #define pp printf
    #define hh pp("
    ")
    using namespace std;
    
    const int N = 2e5 + 5;
    
    ll n, k, T;
    ll x[N];
    
    #define db double
    
    db a[N], b[N]; int a0, b0;
    db c[N], d[N]; int c0, d0;
    
    struct P {
    	db x, y;
    	P(db _x = 0, db _y = 0) {
    		x = _x, y = _y;
    	}
    };
    
    P p[N], q[N]; int p0, q0;
    
    void build(db *a, int &a0, db *c, int &c0) {
    	db s = 0; int la = 0;
    	fo(i, 1, a0) {
    		s += a[i];
    		if(s >= 0) s = 0, la = i;
    	}
    	fd(i, a0, la + 1) c[++ c0] = -a[i];
    	a0 = la;
    }
    
    void build(db *a, int &a0, P *p, int &p0) {
    	db s = 0, mx = 0;
    	fo(i, 1, a0) {
    		s += a[i];
    		mx = max(mx, -s);
    		if(s >= 0) {
    			p[++ p0] = P(mx, s);
    			s = 0, mx = 0;
    		}
    	}
    }
    
    int work(db &z, P *p, int &p0, P *q, int &q0) {
    	if(z < 0) return 0;
    	int l = 1, r = 1;
    	while(l <= p0 || r <= q0) {
    		if(l <= p0 && z >= p[l].x) {
    			z += p[l ++].y;
    			continue;
    		}
    		if(r <= q0 && z >= q[r].x) {
    			z += q[r ++].y;
    			continue;
    		}
    		return 0;
    	}
    	return 1;
    }
    
    int pd(ll mi) {
    	a0 = b0 = c0 = d0 = 0;
    	fd(i, k - 1, 1) {
    		a[++ a0] = (db) -(x[i + 1] - x[i]) / mi / 2;
    		a[++ a0] = T;
    	}
    	fo(i, k + 1, n) {
    		b[++ b0] = (db) -(x[i] - x[i - 1]) / mi / 2;
    		b[++ b0] = T;
    	}
    	
    	build(a, a0, c, c0);
    	build(b, b0, d, d0);
    	
    	p0 = q0 = 0;
    	build(a, a0, p, p0);
    	build(b, b0, q, q0);
    	
    	db z = T;
    	if(!work(z, p, p0, q, q0)) return 0;
    	
    	fo(i, 1, c0) z -= c[i];
    	fo(i, 1, d0) z -= d[i];
    	
    	p0 = q0 = 0;
    	
    	build(c, c0, p, p0);
    	build(d, d0, q, q0);
    	
    	return work(z, p, p0, q, q0);
    }
    
    int main() {
    	scanf("%lld %lld %lld", &n, &k, &T);
    	fo(i, 1, n) scanf("%lld", &x[i]);
    	if(x[1] == x[n]) {
    		pp("0
    "); return 0;
    	}
    	ll as = 0;
    	for(ll l = 1, r = 1e18; l <= r; ) {
    		ll m = l + r >> 1;
    		if(pd(m)) as = m, r = m - 1; else l = m + 1;
    	}
    	pp("%lld
    ", as);
    }
    
  • 相关阅读:
    转载 设计模式大集锦 程序员面试全攻略
    转载 如何给项目选择最合适的编程语言?
    python–ntohll和htonll的实现(转载)
    python 动态加载模块和类
    转载 推荐9个非常有用的开发技巧给Web开发者
    python PyDev统一编码
    mysql 设置编码
    Python MySQLdb.connect连接lampp中mysql服务器问题的解决
    转载 Python编码时的注意事项
    转载 Web前端:11个让你代码整洁的原则
  • 原文地址:https://www.cnblogs.com/coldchair/p/12968747.html
Copyright © 2011-2022 走看看