hdu 4341 Gold miner(分组01背包)

原创 2014年03月07日 20:24:39

http://acm.hdu.edu.cn/showproblem.php?pid=4341


看到这个图好亲切,黄金矿工,很好玩的游戏。。。

题意:矿工起初在(0,0)位置,有n种金矿,给出每种金矿的坐标,花费时间和价值。在同一条线上的金矿必须先抓近的再抓远的,若近的不抓没办法抓远的。要求在T时间内获得的最大价值。


思路:01背包问题,但需要变形。 变形之处就是解决在同一条线上的金矿。 分组背包,把在同一条线上的金矿分为同一组。先按斜率排序,斜率相等按距离排序。例如1,2,3,4,5,五种金矿,根据斜率计算出1和2;3和4斜率分别相等,那么可分为(1,2)(3,4)(5)三组。在这里由于先抓近的再抓远的,对于(3,4)一组,把3物品的时间和价值加到4物品上作为4物品的时间和价值。这样就对应了分组背包每组最多取一件。 形成分组背包模型后直接套模板。

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;

int n,T;
struct node
{
	int x,y;
	int t,v;
	bool operator < (const struct node &tmp)const
	{

		if(y*tmp.x == x*tmp.y)//斜率相等,按距离从小到大排序,不能按y/x排,因为x可能为0.
			return y < tmp.y;
		return y*tmp.x < x*tmp.y;
	}
}point[210];

vector <struct node> edge[210];//保存分组后的状态
int cnt;
int dp[40010];

int solve()
{
	memset(dp,0,sizeof(dp));
	for(int i = 0; i <= cnt; i++)
	{
		for(int j = T; j >= edge[i][0].t; j--)
		{
			for(int k = 0; k < (int)edge[i].size(); k++)
				dp[j] = max(dp[j], dp[j-edge[i][k].t]+edge[i][k].v);
		}
	}
	return dp[T];
}

int main()
{
	int item = 1;
	while(~scanf("%d %d",&n,&T))
	{
		for(int i = 0; i < n; i++)
			scanf("%d %d %d %d",&point[i].x,&point[i].y,&point[i].t,&point[i].v);


		sort(point,point+n);

		for(int i = 0; i < n; i++)
			edge[i].clear();

		cnt = 0;
		edge[cnt].push_back(point[0]);

		for(int i = 1; i < n; i++)	//n件物品分组
		{
			if(point[i].x*point[i-1].y == point[i].y*point[i-1].x)
				edge[cnt].push_back(point[i]);
			else edge[++cnt].push_back(point[i]);
		}

		for(int i = 0; i <= cnt; i++)
		{
			//修改同一条线上的金矿的时间和价值
			for(int j = 1; j < (int)edge[i].size(); j++)
			{
				edge[i][j].t += edge[i][j-1].t;
				edge[i][j].v += edge[i][j-1].v;
			}
		}
		printf("Case %d: %d\n",item++,solve());
	}
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013081425/article/details/20731345

hdu 4341 分组背包

http://acm.hdu.edu.cn/showproblem.php?pid=4341 Problem Description Homelesser likes playing Gol...
  • u013573047
  • u013573047
  • 2015-02-05 10:15:32
  • 584

HDU 4341 Gold miner

题目链接 题意:一个人在原点(0,0)抓金子,n~200个金子,每块金子有一个获得需要的时间t和价值v。而且有的金子可能在一条直线上,那只能先抓近的,再抓远的。求在给定时间T~40000下,所能获得...
  • u013625492
  • u013625492
  • 2015-03-13 10:47:54
  • 262

hdu 4341 gold miner

受教了。这个题目是本人第一次做分组背包,比较失败。连题意带条件搞错了几个地方,最终悲剧的wa了4次。 #include #include #include using namespace std; ...
  • zhuyongqingacm
  • zhuyongqingacm
  • 2013-08-15 22:14:13
  • 568

HDU 4341 - Gold miner

B - Gold miner Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit...
  • leifjacky
  • leifjacky
  • 2016-04-26 17:01:23
  • 353

Hdu 4341 Gold miner

Gold miner Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot...
  • Magic____
  • Magic____
  • 2012-10-08 13:06:10
  • 418

hdu 4341 Gold miner

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4341 //author:zhengjj.asd@gmail.com //要取ai位置的黄金的话,必须把斜...
  • zhengjj_asd
  • zhengjj_asd
  • 2012-08-11 13:26:59
  • 352

HDU 4341 Gold miner (分组背包问题)

Gold miner Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To...
  • acbron
  • acbron
  • 2013-04-10 21:01:16
  • 305

HDU 4341 Gold miner (分组背包)

题意:一个人在原点(0,0)抓金子,每块金子有一个获得需要的时间t和价值v。而且有的金子可能在一条直线上,那只能先抓近的,再抓远的。求在给定时间T下,所能获得的最大价值。 这题可以转化为分组的...
  • u013491262
  • u013491262
  • 2014-03-12 22:45:56
  • 607

hdu acm 4341 Gold miner

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(...
  • hyf20144055065
  • hyf20144055065
  • 2015-10-02 11:58:16
  • 313

hdu 4341 Gold miner 分组背包

题意:矿工起初在(0,0)位置,有n种金矿,给出每种金矿的坐标,花费时间和价值。在同一条线上的金矿必须先抓近的再抓远的,若近的不抓没办法抓远的。要求在T时间内获得的最大价值。完全没有想到使用分组背包来...
  • Little_boy_z
  • Little_boy_z
  • 2018-02-09 18:31:41
  • 11
收藏助手
不良信息举报
您举报文章:hdu 4341 Gold miner(分组01背包)
举报原因:
原因补充:

(最多只允许输入30个字)