UPC-6349: Talent Show【二分+DP】

6349: Talent Show

時間限制: 1 Sec  內存限制: 128 MB
提交: 163  解決: 59
[提交] [狀態] [討論版] [命題人: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.

 

題意:有n件物品,重量分別是wi,價值是ti,要求在滿足wi的和大於等於W的情況下,能得到的最大  ti和/wi 和的比,結果向下取整,然後乘1000倍。

思路:sum(ti)/sum(wi) = x.則有sum(ti) = sum(wi)*x. 進一步得出sum(ti)-sum(wi)*x = 0.展開後利用加法交換律得到sum(ti-wi*x) = 0. 此時發現ti,wi可以枚舉,只留下x不確定,然後結果要求是0。考慮二分x,若加起來的和>0,說明x的值小了,若加起來的和<0,說明x大了,然後考慮到和的問題。0 1揹包問題中w的值僅可考慮到最大的w即可不然無法實現或者超時。

代碼實現:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define FIN freopen("D://code//in.txt", "r", stdin)
#define ppr(i,x,n) for(int i = x;i <= n;i++)
#define rpp(i,n,x) for(int i = n;i >= x;i--)
const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;

inline int read() {//讀入掛
    int ret = 0, c, f = 1;
    for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
    if(c == '-') f = -1, c = getchar();
    for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0';
    if(f < 0) ret = -ret;
    return ret;
}
ll n,w;
ll ti[100005],wi[100005];
ll dp[10005];
int judge(ll x)
{
	ppr(i,0,10005)
	dp[i] = -INF;
	dp[0] = 0; 
	ppr(i,1,n)
	{
		rpp(j,w,0)
		{
			ll flag = min(w,wi[i] + j);
			//cout<<flag<<endl;
		//	cout << j <<endl;
			dp[flag] = max(dp[flag],dp[j] + ti[i] - wi[i]*x);
		}
	}
	//cout <<dp[w]<<endl;
	if(dp[w] >= 0)
	return 1;
	else
	return 0;
}
int main()
{
	cin>>n>>w;
	ppr(i,1,n)
	{
		cin>>wi[i]>>ti[i];
		ti[i] *= 1000;
	}
	ll l = 1,r = 100005;
	while(l <= r)
	{
		ll mid = (l + r) >> 1;
		if(judge(mid))
		l = mid + 1;
		else
		r = mid - 1;
	}
	cout<<r<<endl;
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章