1. 程式人生 > >BZOJ5281: [Usaco2018 Open]Talent Show(01分數規劃&DP)

BZOJ5281: [Usaco2018 Open]Talent Show(01分數規劃&DP)

性價比 只需要 ron true 等於 div 獲得 大於 ref

5281: [Usaco2018 Open]Talent Show

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 166 Solved: 124
[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。
思路:分子分母的最大形式顯然需要二分後01分數規劃求最大。 二分到mid的時候,我們按照t-w*mid排序。 這個時候出現問題了,我們是選擇最前面幾個直到體積大於等於W嗎,顯然不是的。 比如需要體積W=120的東西,現在有三種(w,t):(100,100),(70,35),(20,9); 顯然選擇1,3的比值比選擇1,2搞,盡管2的性價比比3高。 主要是因為我們只需要W=120,2的性價比雖然高於3,但是無用的w也多了,拉低了整體性價比。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;
struct in{
    int w,t; double xjb;
    friend bool operator <(in w,in v){ return w.xjb>v.xjb; }
}s[maxn];int N,W; double dp[maxn];
bool check(double Mid)
{
    for(int i=1;i<=N;i++) s[i].xjb=(double)s[i].t-Mid*s[i].w;
    sort(s+1,s+N+1);
    for(int i=1;i<=W;i++) dp[i]=-1000000000.0; dp[0]=0.0;
    for(int i=1;i<=N;i++){
        for(int j=W;j>=0;j--){
            if(j+s[i].w>=W){
                if(dp[j]+s[i].xjb>=0) return true;
            }
            else dp[j+s[i].w]=max(dp[j+s[i].w],dp[j]+s[i].xjb);
        }
    }
    return false;
}
int main()
{
    scanf("%d%d",&N,&W);
    for(int i=1;i<=N;i++) scanf("%d%d",&s[i].w,&s[i].t);
    double L=0,R=1000000.0,Mid,ans=111; int num=100;
    while(num--){
        Mid=(L+R)/2;
        if(check(Mid)) L=Mid,ans=L;
        else R=Mid;
    }
    printf("%d\n",(int)(ans*1000));
    return 0;
}

BZOJ5281: [Usaco2018 Open]Talent Show(01分數規劃&DP)