USACO18OPEN Talent Show G

P4377 [USACO18OPEN] Talent Show G

题目大意

n n n头奶牛,第 i i i头奶牛的重量为 w i w_i wi,才艺水平为 t i t_i ti。你需要选择若干头奶牛,使得

  • 这些奶牛的总重量至少为 W W W
  • 总才艺值与总重量的比值最大的一组获胜

这些奶牛的总重量大于等于 W W W,求选择若干头奶牛能够达到的才艺与重量的比值的最大值,并输出这个最大值成一千再向下取整后的值。

1 ≤ n ≤ 250 , 1 ≤ W ≤ 1000 , 1 ≤ w i ≤ 1 0 6 , 1 ≤ t i ≤ 1 0 3 1\leq n\leq 250,1\leq W\leq 1000,1\leq w_i\leq 10^6,1\leq t_i\leq 10^3 1n250,1W1000,1wi106,1ti103


题解

二分答案,设当前二分的值为 m i d mid mid,则

∑ t i ∑ w i ≥ m i d \dfrac{\sum t_i}{\sum w_i}\geq mid witimid

由此可得

∑ t i ≥ m i d × ∑ w i \sum t_i\geq mid\times \sum w_i timid×wi

移项得

∑ ( t i − m i d × w i ) ≥ 0 \sum(t_i-mid\times w_i)\geq 0 (timid×wi)0

v i = t i − m i d × w i v_i=t_i-mid\times w_i vi=timid×wi,那么每头奶牛的重量为 w i w_i wi,价值为 w i w_i wi,用背包即可解决。重量大于等于 W W W的都记录在 f W f_W fW中。最后只需判断 f W f_W fW是否大于 0 0 0即可。

为了方便,所有 t t t值在一开始就乘了 1000 1000 1000

时间复杂度为 O ( n w log ⁡ S ) O(nw\log S) O(nwlogS),其中 S = ∑ w i S=\sum w_i S=wi

code

#include<bits/stdc++.h>
using namespace std;
int n,w;
long long f[305][1005];
struct node{
	int w,t;
}v[305];
bool check(long long k){
	for(int i=0;i<=n;i++){
		for(int j=0;j<=w;j++) f[i][j]=-1e15;
	}
	f[0][0]=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<=w;j++) f[i][j]=f[i-1][j];
		for(int j=0;j<=w;j++){
			f[i][min(j+v[i].w,w)]=max(f[i][min(j+v[i].w,w)],f[i-1][j]+v[i].t-k*v[i].w);
		}
	}
	return f[n][w]>=0;
}
int main()
{
	scanf("%d%d",&n,&w);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&v[i].w,&v[i].t);
		v[i].t*=1000;
	}
	int l=0,r=3e8,mid;
	while(l<=r){
		mid=l+r>>1;
		if(check(mid)) l=mid+1;
		else r=mid-1;
	}
	printf("%d",l-1);
	return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值