NYOJ 824 Greedy Mouse (物体可分割背包问题,尽可能让价值总量最大)

Greedy Mouse

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述

A fat mouse prepared M pounds of cat food,ready to trade with the cats guarding the warehouse containing his

favorite food:peanut. The warehouse has N rooms.The ith room containsW[i] pounds of peanut and requires 

F[i] pounds of cat food. Fatmouse does not have to trade for all the peanut in the room,instead,he may get 

 W[i]*a% pounds of peanut if he pays F[i]*a% pounds of cat food.The mouse is a stupid mouse,so can you tell 

him the maximum amount of peanut he can obtain.

输入
The input consists of multiple test cases. Each test case begins with a line containing two non-negative integers M and N. Then N lines follow, each contains two non-negative integers W[i] and F[i] respectively. The test case is terminated by two -1. All integers are not greater than 1000.
输出
For each test case, print in a single line a real number accurate up to 3 decimal places, which is the maximum amount of penaut that FatMouse can obtain.
样例输入
5 3
7 2
4 3
5 2
20 3
25 18
24 15
15 10
-1 -1
样例输出
13.333
31.500
//即可抽象为部分背包问题: n 个物体,第 i 个物体的重量为 wi ,价值为 vi ,在总重量不超过 C 的情况下,让总价值尽量高。而且可以拿走物体的一部分。

AC代码:

用while循环:

#include <stdio.h>
#include <algorithm>
using namespace std;
struct node 
{
double v,cost,c;//价值  买完应该花的  单价 
}a[1005];
int cmp(node x,node y)
{
if(x.c<y.c) return 1;
else if(x.c==y.c&&x.v>y.v) return 1;
return 0;//最便宜的且数量多的排在前面 

int main()
{
double m;
int n;
while(~scanf("%lf %d",&m,&n))
{
if(m==-1&&n==-1) return 0;
for(int i=0;i<n;i++)
{
scanf("%lf %lf",&a[i].v,&a[i].cost);
a[i].c=a[i].cost/a[i].v;
}
sort(a,a+n,cmp);
double ans=0;
int i=0;
while(m>0&&i<n)
//注意:一定要加i<n,因为有可能老鼠把猫的粮食换完后老鼠的粮食还没用完 
   //如果不加,就有可能while循环不能终止,WA 
{
if(m>=a[i].cost) //能全部换过来就全部换过来,因为当前是最便宜的 
{
ans+=a[i].v;
m-=a[i].cost;
i++;

else 
{
ans+=m/a[i].c;//剩下的钱/单价=还能买多少 
m=0;
}
}
printf("%.3lf\n",ans);
}
return 0;


用for循环:

 
#include <stdio.h>
#include <algorithm>
using namespace std;
struct room
{
double food;
double cost;
}a[1100]; 
int cmp(room x,room y)
{
if(x.food/x.cost>y.food/y.cost) return 1;
else return 0;
}
int main()
{
  double m,w;
  int i,n;
  while(~scanf("%lf %d",&m,&n))
  {
  if(n==-1&&m==-1) return 0;
  for(i=0;i<n;i++)
  scanf("%lf %lf",&a[i].food,&a[i].cost);
  sort(a,a+n,cmp);
  double sum=0; 
  for(i=0;i<n;i++)
  {
  if(m>=a[i].cost) sum=sum+a[i].food;
else 
{
w=m/a[i].cost; 
sum=sum+w*a[i].food;
break;
}
m=m-a[i].cost;   
  }
  printf("%.3lf\n",sum);
  }
  return 0;
 }         

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值