• HDU 6240 Server(2017 CCPC哈尔滨站 K题,01分数规划 + 树状数组优化DP)


    题目链接  2017 CCPC Harbin Problem K

    题意  给定若干物品,每个物品可以覆盖一个区间。现在要覆盖区间$[1, t]$。

       求选出来的物品的$frac{∑a_{i}}{∑b_{i}}$的最小值。

     

    首先二分答案,那么每个物品的权值就变成了$x * b_{i} - a_{i}$

    在判断的时候先把那些权值为正的物品全部选出来,

    然后记录一下从$1$开始可以覆盖到的最右端点的位置。

    接下来开始DP,按照区间的端点升序排序(左端点第一关键字,右端点第二关键字)

    问题转化为能否用剩下的物品覆盖尚未覆盖的区间。

    那么直接用树状数组优化DP就可以了。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define	rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define	dec(i, a, b)	for (int i(a); i >= (b); --i)
    #define	fi		first
    #define	se		second
    
    const int N = 1e5 + 10;
    
    struct node{
    	int s, t;
    	double a, b;
    	bool flag;
    	void scan(){ scanf("%d%d%lf%lf", &s, &t, &a, &b); }
    
    	friend bool operator < (const node &a, const node &b){
    		return a.s == b.s ? a.t < b.t : a.s < b.s;
    	}
    } a[N];
    
    int T;
    int n, m;
    double c[N];
    double l, r;
    
    
    void update(int x, double val){
    	for (; x; x -= x & -x) c[x] = min(c[x], val);
    }
    
    double query(int x){
    	if (x == 0) return 0;
    	double ret = 1e9;
    	for (; x <= m; x += x & -x) ret = min(ret, c[x]);
    	return ret;
    }
    
    bool check(double x){
    	int mx = 0;
    	double ss = 0;
    	rep(i, 0, m) c[i] = 1e9;
    
    	rep(i, 1, n){
    		if (a[i].b * x - a[i].a > 0){
    			ss += a[i].b * x - a[i].a;
    			a[i].flag = true;
    
    			if (a[i].s - 1 <= mx){
    				mx = max(mx, a[i].t);
    			}
    		}
    
    		else a[i].flag = false;
    	}
    
    	if (mx == m) return true;
    	update(mx, 0);
    
    	rep(i, 1, n){
    		if (!a[i].flag){
    			double mi = query(a[i].s - 1);
    			update(a[i].t, mi + a[i].a - a[i].b * x);
    		}
    
    		else{
    			double mi = query(a[i].s - 1);
    			update(a[i].t, mi);
    		}
    	}
    
    	return ss >= query(m);
    }
    
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d%d", &n, &m);
    		rep(i, 1, n) a[i].scan();
    		sort(a + 1, a + n + 1);
    
    		l = 0, r = 1e3 + 10;
    
    		rep(i, 1, 50){
    			double mid = (l + r) / 2.00;
    			if (check(mid)) r = mid;
    			else l = mid;
    		}
    
    		printf("%.3f
    ", l);
    	}
    
    	return 0;
    
    }
    

     

  • 相关阅读:
    Classic Source Code Collected
    Chapter 2 Build Caffe
    蓝屏代码大全 & 蓝屏全攻略
    AMD C1E SUPPORT
    DCU IP Prefether
    DCU Streamer Prefetcher
    adjacent cache line prefetch
    Hardware Prefetcher
    Execute Disable Bit
    Limit CPUID MAX
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8861918.html
Copyright © 2020-2023  润新知