• BZOJ 5281--[Usaco2018 Open]Talent Show(分数规划&单调队列&DP)


    5281: [Usaco2018 Open]Talent Show

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 79  Solved: 58
    [Submit][Status][Discuss]

    Description

    FarmerJohn要带着他的N头奶牛,方便起见编号为1…N,到农业展览会上去,参加每年的达牛秀!他的第i头奶牛重量为wi,才艺水平为ti,两者都是整数。在到达时,FarmerJohn就被今年达牛秀的新规则吓到了:
     
    (一)参加比赛的一组奶牛必须总重量至少为W
     
    (这是为了确保是强大的队伍在比赛,而不仅是强大的某头奶牛),并且
     
    (二)总才艺值与总重量的比值最大的一组获得胜利。
     
    FJ注意到他的所有奶牛的总重量不小于W,所以他能够派出符合规则(一)的队伍。帮助他确定这样的队伍中能够达到的最佳的才艺与重量的比值。
     

    Input

    输入的第一行包含N和W。下面N行,每行用两个整数wi和ti描述了一头奶牛。
    1≤N≤250
    1≤W≤1000
    1≤wi≤10^6
    1≤ti≤10^3
     

    Output

    请求出Farmer用一组总重量最少为W的奶牛最大可能达到的总才艺值与总重量的比值。
    如果你的答案是A,输出1000A向下取整的值,以使得输出是整数
    (当问题中的数不是一个整数的时候,向下取整操作在向下舍入到整数的时候去除所有小数部分)。
     

    Sample Input

    3 15
    20 21
    10 11
    30 31

    Sample Output

    1066
    在这个例子中,总体来看最佳的才艺与重量的比值应该是仅用一头才艺值为11、重量为10的奶牛,但是由于我们需
    要至少15单位的重量,最优解最终为使用这头奶牛加上才艺值为21、重量为20的奶牛。这样的话才艺与重量的比值
    为(11+21)/(10+20)=32/30=1.0666666...,乘以1000向下取整之后得到1066。
     

    题目链接:

        http://www.lydsy.com/JudgeOnline/problem.php?id=5281 

    Solution

      一看题面就知道要01分数规划。。。

      假设答案为c,式子比较显然 ti的总和 / wi的总和 >= c

      ti的总和 >=  wi的总和 * c

      然后就是二分c验证正确性。。

      将每只牛的价值赋值为 ti - wi * c

      显然如果有一种方案使得总的牛的价值不小于0,就说明c存在合法方案。。

      由于W<=1000,我们可以直接DP。。

      f [ i ] 表示wi总和不小于i时的最大价值总和。。

      f [ i ] = max(f[j]+val)其中val表示当前牛的价值,并且i-j<=w

      由于i和j的关系,要用单调队列维护。。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<map>
    #include<cmath>
    #include<set>
    #define pa pair<LL,LL>
    #define LL long long
    #define ept 1e-5
    using namespace std;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline void Out(int a){
        if(a>9) Out(a/10);
        putchar(a%10+'0');
    }
    const double inf=1e9;
    const LL mod=1e9+7;
    const int N=300;
    int n,m,cnt=1,W;
    struct cow{
    	int w,s;
    }a[N];
    double f[2000],t[2000];
    int q[2000];
    
    int main(){
        n=read();W=read();
    	for(int i=1;i<=n;++i){
    		a[i].w=read();a[i].s=read();
    	}
    	double l=0,r=10000,mid,y;
    	int x,L=1,R=0;
    	while(fabs(r-l)>ept){
    		//cout<<l<<" "<<r<<endl;
    		mid=(l+r)/2;
    		for(int i=0;i<=W;++i) f[i]=-inf;
    		f[0]=0;
    		for(int i=1;i<=n;++i){
    			x=a[i].w<=W?a[i].w:W;
    			y=(double)a[i].s-(double)mid*(double)a[i].w;
    			L=1;R=1;q[1]=0;
    			for(int j=1;j<=W;++j){
    				while(L<=R&&f[j]>f[q[R]]) --R;
    				q[++R]=j;
    				while(j-q[L]>x) ++L;
    				t[j]=f[q[L]]+y;
    			}
    			for(int j=1;j<=W;++j)
    				if(t[j]>f[j]) f[j]=t[j];
    		}
    		if(f[W]>=0) l=mid;
    		else r=mid; 
    	}
    	l=l*1000;
    	int ans=l;
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

      

    This passage is made by Iscream-2001.

  • 相关阅读:
    Objective-C Runtime 运行时之四:Method Swizzling
    App启动加载广告页面思路
    关于CoreData和SQLite多线程访问时的线程安全问题
    HIVE学习(待更新)
    流处理环境搭建
    CAJ2PDF
    ArcMap加载在线地图
    学习opencv(持续更新)
    风险和策略(待更新)
    区块链入门教程(转)
  • 原文地址:https://www.cnblogs.com/Yuigahama/p/9680351.html
Copyright © 2020-2023  润新知