0/1分数规划+0/1背包模型(p4377)

3 篇文章 0 订阅
3 篇文章 0 订阅

发现又是一道求max \frac{\sum_{i=1}^{n}t_{i}s_{i}}{\sum_{i=1}^{n}w_{i}s_{i}} 的0/1分数规划的题目,与普通的0/1分数规划不同的是,这题加了一个限制条件,总重量不低于W,我们只要把重量超过w看成等于w,这题不就是一个0/1背包问题。

对于0/1分数规划问题:(3条消息) 0/1分数规划(poj2976)_Knight840的博客-CSDN博客

对于0/1背包问题:dp[j]表示重量为j的最大权值,由于每个物品只有一个,且dp[j]是由比j小的值确定,如果从小到大遍历j,就会用到这一轮更新过的dp值,可能导致一轮不止用一次第i个物品的值,所以遍历j要从大到小遍历。

#include<bits/stdc++.h>
using namespace std;
int n,w;
double dp[10000];
struct node
{
	int w;
	int t;
	double y;
}h[1005];
bool check(double m)
{
	for(int i=0;i<n;i++)
	{
		h[i].y=h[i].t*1.0-m*h[i].w; 
	}
	for(int i=1;i<=w;i++)
	{
		dp[i]=-0x3f3f3f3f;
	}
	dp[0]=0;
	//0/1背包 
	for(int i=0;i<n;i++)
	{
		for(int j=w;j>=0;j--)//一定是从大到小遍历 
		{
			if(j+h[i].w>=w)
			{
				dp[w]=max(dp[w],dp[j]+h[i].y);
			}
			else dp[j+h[i].w]=max(dp[j+h[i].w],dp[j]+h[i].y);
		}
	}
	if(dp[w]>=0)return 1;
	else return 0;
}
int main()
{
	cin>>n>>w;
	for(int i=0;i<n;i++)
	{
		cin>>h[i].w>>h[i].t; 
	}
	double l=0,r=0;
	for(int i=0;i<n;i++)
	{
		r+=h[i].t;
	}
	for(int i=0;i<=50;i++)
	{
		double mid=(l+r)/2;
		if(check(mid))
		{
			l=mid;
		}
		else 
		{
			r=mid;
		}
	}
	cout<<(int)(1000*l)<<endl;
	return 0;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值