版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/monochrome00/article/details/88534564
题目链接<http://10.7.88.2/CLanguage/showproblem?problem_id=2268>
题意:
给出n头奶牛的重量w和才艺值t,要求挑出若干只牛,使得大于等于w,且最大。
题解:
01分数规划:设,则,如果,证明偏小,否则偏大。这样就可以二分答案了。
判断的时候用01背包来判断能否挑出一些体重之和大于等于的奶牛,且。
这时候的背包就只要枚举到w即可,dp[w]表示的是所有大于等于w中最大的状态。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#define ll long long
using namespace std;
const ll N=1e3+7;
ll md;
ll a[N],b[N];
ll w,n;
ll dp[N];
bool jg(ll md){
memset(dp,-125,sizeof(dp));
dp[0]=0;
for(ll i=1;i<=n;i++){
for(ll j=w;j>=0;j--){
if(dp[j]<=dp[w+1]) continue;
ll k=min(w,a[i]+j);
dp[k]=max(dp[k],dp[j]+b[i]-md*a[i]);
}
}
return dp[w]>=0;
}
int main()
{
scanf("%lld%lld",&n,&w);
for(ll i=1;i<=n;i++){
scanf("%lld%lld",&a[i],&b[i]);
b[i]*=1000;
}
ll lo=0,hi=1e6,ans;
while(lo<=hi){
md=lo+hi>>1;
if(jg(md)) ans=md,lo=md+1;
else hi=md-1;
}
printf("%lld\n",ans);
}