用户操作
[留言]  [发消息]  [加为好友] 
订阅我的博客
XML聚合    FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
cblhxx的公告
文章分类
存档

原创  背包问题 收藏

题目:从n个不同价值、不同重量的物品中选取一部分,在不超过限定的总重量的前提下,使该部分的价值最大。这里假定的总重量不超过n个物品的总重量总和,且没有一样物品的重量超过限定的总重量。

分析: 如果用x表示物品的重量, y表示物品价值, y/x斜率表示物品的单位价值. 那么通过斜率给所有物品排序后,  按顺序从大到小选取物品就是一种总价值比较大的的方法,  并且每一次选取的物品斜率递减. 用当前总价值/当前总重量得到一个当前总斜率, 如果希望得到一种选取方法使最后的价值大于当前总价值, 那么必须保证每一次选取物品的斜率都要大于当前总斜率(因为每次选取的物品斜率都是递减的, 如果选取的物品斜率小于等于总斜率, 那么最后的价值不可能超过总价值)

代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>


using namespace std;


class Point
{
public:
 int x;
 int y;
 double ymulx;

 Point(int xx, int yy) :x(xx), y(yy) {ymulx = (double)y/x;}

 friend bool operator> (const Point& p1,const Point& p2)
 {
  return p1.ymulx > p2.ymulx;
 }
 friend bool operator< (const Point& p1,const Point& p2)
 {
  return p1.ymulx < p2.ymulx;
 }

 friend void print(Point& p)
 {
  cout<<p.x<<" "<<p.y<<" "<<p.ymulx<<endl;
 }
};


int getmax_y(int limit_x, Point* it, const Point* it_end);
int getmax_y(int limit_x, int limit_y, Point* it, const Point* it_end);


int main()
{
 int x, y, limit_x;
 vector<Point> vp;

 cin>>limit_x;

 while(cin>>x>>y)
 {
  vp.push_back(Point(x,y));
 }

 sort(vp.begin(), vp.end(), greater<Point>());
 cout<<getmax_y(limit_x, vp.begin(), vp.end())<<endl;

 return 0;
}

int getmax_y(int limit_x, Point* it, const Point* it_end)
{
 int limit_y = 0, temp_limit_x = limit_x;
 Point* temp_it = it;

 if(limit_x == 0) return 0;
 while(temp_it < it_end)
 {
  if(temp_it->x <= temp_limit_x)
  {
  temp_limit_x = temp_limit_x - temp_it->x;
  limit_y = limit_y + temp_it->y;
  }
  temp_it++;
 }

 if(limit_y == 0) return 0;
 return getmax_y(limit_x, limit_y, it, it_end);
}


int getmax_y(int limit_x, int limit_y, Point* it, const Point* it_end)
{
 Point temp_point(limit_x, limit_y);
 int max_y = 0, temp;

 while(it < it_end)
 {
  if(*it < temp_point) break;
  if(it->x > limit_x) {it++; continue;}
  if(it->y > limit_y)
  {
   max_y = it->y + getmax_y(limit_x - it->x, it+1, it_end);
   temp_point = Point(limit_x, max_y);
   it++;
   continue;
  }
  temp = getmax_y(limit_x - it->x, limit_y - it->y, it+1, it_end) + it->y;
  if(temp > max_y) max_y = temp;
  it++;
 }

 return max_y;
}

 

发表于 @ 2006年10月04日 20:43:00 | 评论( loading... ) | 编辑| 举报| 收藏

新一篇:临时剪切板

  • 发表评论
  • 评论内容:
  •  
Copyright © cblhxx
Powered by CSDN Blog