Talent Show 分数规划加背包dp(还不太懂)

6349: Talent Show

时间限制: 1 Sec  内存限制: 128 MB
提交: 170  解决: 63
[提交] [状态] [讨论版] [命题人:admin]

题目描述

Farmer John is bringing his N cows, conveniently numbered 1…N, to the county fair, to compete in the annual bovine talent show! His ith cow has a weight wiwi and talent level ti, both integers.
Upon arrival, Farmer John is quite surprised by the new rules for this year's talent show:

(i) A group of cows of total weight at least W must be entered into the show (in order to ensure strong teams of cows are competing, not just strong individuals), and

(ii) The group with the largest ratio of total talent to total weight shall win.

FJ observes that all of his cows together have weight at least W, so he should be able to enter a team satisfying (i). Help him determine the optimal ratio of talent to weight he can achieve for any such team.

 

输入

The first line of input contains N (1≤N≤250) and W (1≤W≤1000). The next N lines each describe a cow using two integers wi (1≤wi≤106) and ti (1≤ti≤103).

 

输出

Please determine the largest possible ratio of total talent over total weight Farmer John can achieve using a group of cows of total weight at least W. If your answer is A, please print out the floor of 1000A in order to keep the output integer-valued (the floor operation discards any fractional part by rounding down to an integer, if the number in question is not already an integer).

 

样例输入

3 15
20 21
10 11
30 31

 

样例输出

1066

 

提示

In this example, the best talent-to-weight ratio overall would be to use just the single cow with talent 11 and weight 10, but since we need at least 15 units of weight, the optimal solution ends up being to use this cow plus the cow with talent 21 and weight 20. This gives a talent-to-weight ratio of (11+21)/(10+20) = 32/30 = 1.0666666..., which when multiplied by 1000 and floored gives 1066.

选出一部分使得t/w平均值最大

先用分数规划的思想(其实我更喜欢叫二分),然后再用背包判定(背包里有一步不太懂,先贴出来,以后慢慢理解)

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxx=2e5+100;
const ll INF=1e15;
const int MOD=1e9+7;
const double eps=1e-8;
ll n,we;
ll w[maxx],t[maxx];
ll dp[maxx];
ll noww[maxx];
bool ask(ll x)
{
    for(int i=1; i<=we; i++)
        dp[i]=-INF;
    for(int i=1; i<=n; i++)
        noww[i]=1000*t[i]-x*w[i];
    for(int i=1; i<=n; i++){
        for(int j=we; j>=we-w[i] && ~j; j--)
            dp[we]=max(dp[we],dp[j]+noww[i]);
        for(int j=we-1; j>=w[i]; j--)
            dp[j]=max(dp[j],dp[j-w[i]]+noww[i]);
    }
    return dp[we]>=0;
}
int main()
{
    cin>>n>>we;
    for(int i=1; i<=n; i++){
        cin>>w[i]>>t[i];
    }
    ll l=1,r=1e6+1;
    while(r-l>1){
        ll mid=(l+r)>>1;
        if(ask(mid)){
            l=mid;
        }
        else  r=mid;
    }
    cout<<l<<endl;
    return 0;
}

 

posted @ 2018-07-28 09:56  任小喵  阅读(191)  评论(0编辑  收藏  举报