LG4377 「USACO2018OPEN」Talent Show 线性规划+背包

Posted liubainian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LG4377 「USACO2018OPEN」Talent Show 线性规划+背包相关的知识,希望对你有一定的参考价值。

问题描述

LG4377


题解

(n) 个物品,每个物品有两个权值 (a,b)

需要确定一组 (w_i in [0,1]) ,使得 (frac{sum{w_i imes a_i}}{sum{w_i imes b_i}}) 最大。

要求 (sum{w_i imes b_i ge W})

分数规划,二分答案的 (mathrm{check}) 函数采用背包进行判断。


(mathrm{Code})

#include<bits/stdc++.h>
using namespace std;

template <typename Tp>
void read(Tp &x){
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
    if(ch=='-') ch=getchar(),fh=-1;
    else fh=1;
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    x*=fh;
}

const int maxn=1007;

int n,w;
int a[maxn];
int b[maxn];
long long f[maxn];
bool check(int mid){
    memset(f,0xcf,sizeof(f));
    f[0]=0;
    for(int i=1;i<=n;i++){
        for(int j=w;j>=0;j--){
            if(f[j]==f[w+1]) continue;
            int pos=min(w,j+a[i]);
            f[pos]=max(f[pos],f[j]+b[i]-(long long)a[i]*mid);
        }
    }
    return f[w]>=0;
}

int main(){
    read(n);read(w);
    for(int i=1;i<=n;i++) cin>>a[i]>>b[i],b[i]*=1000;
    int L=0,R=1000000;
    while(L<=R){
        int mid=(L+R)>>1;
        if(check(mid)) L=mid+1;
        else R=mid-1;
    }
    printf("%d
",L-1);
    return 0;
}

以上是关于LG4377 「USACO2018OPEN」Talent Show 线性规划+背包的主要内容,如果未能解决你的问题,请参考以下文章

[bzoj5278][Usaco2018 Open]Out of Sorts

[USACO 2018 Open Gold] Tutorial

[Usaco2018 Open]Disruption

[Usaco2018 Open]Milking Order

[Usaco2018 Open]Talent Show

LG2996 「USACO10NOV」Visiting Cows