模拟黄金矿工这个游戏,给出每一个金子的位置和所需时间,计算在给定时间内最大收益。

刚看这道题以为金子的位置没什么用,直接DP就行,WA了一发终于明白如果金子和人共线的话只能按顺序抓。

这就是需要考虑先后关系问题。看了背包⑨讲之后以为是“有依赖关系的背包”,感觉解决方案很不明显,想不出来做法。

后来想到,可以把共线的金子按1,1+2,1+2+3。。。变成若干个,然后共线的金子组成一组。

显然这个问题就变成了在组内互斥的情况下的分组DP,背包⑨讲已经给出了伪代码。

预处理的时候使用了优先队列,map,乱搞了一下就好了。。。//好不容易自己写出来了一道不太水的题。。。

 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <stack>
#include <map> using namespace std; const int maxn = +; struct node
{
int x,y;
int w,v;
node(){x=;y=;w=;v=;}
node(int x,int y) {w=x;v=y;}
bool operator < (const node &b) const
{
return x*x+y*y > b.x*x+b.y*y;
} }gold[maxn]; struct item
{
int w,v;
item(){w=;v=;}
item(int a,int b){w=a;v=b;}
}; int x[maxn],y[maxn],w[maxn],v[maxn],dp[];
int N,T;
vector <item> itm[maxn]; int main()
{
int cas = ;
while(~scanf("%d%d",&N,&T))
{
map<pair<int,int> , int > mp;
priority_queue<node> pq[maxn];
int cnt_group = ;
for(int i=;i<maxn;i++) itm[i].clear(); for(int i=,x,y;i<N;i++)
{
scanf("%d%d%d%d",&gold[i].x,&gold[i].y,&gold[i].w,&gold[i].v);
x = gold[i].x;y = gold[i].y; if(mp.count(pair<int,int>( x/__gcd(x,y) , y/__gcd(x,y)) ))
{
pq[mp[pair<int,int>( x/__gcd(x,y) , y/__gcd(x,y))]].push(gold[i]);
}
else
{
mp[pair<int,int>( x/__gcd(x,y) , y/__gcd(x,y))]=cnt_group++;
pq[mp[pair<int,int>( x/__gcd(x,y) , y/__gcd(x,y))]].push(gold[i]);
}
} map<pair<int,int>,int >::iterator it;
node cur;
for(int i=;i<cnt_group;i++)
{
cur = node(,);
while(!pq[i].empty())
{
cur.w += pq[i].top().w;
cur.v += pq[i].top().v;
pq[i].pop();
itm[i].push_back(item(cur.w,cur.v));
//printf("grp:%d w:%d v:%d\n",i,cur.w,cur.v);
}
}
memset(dp,,sizeof dp); for(int gp=;gp<cnt_group;gp++)
{
int n = itm[gp].size(); for(int t=T;t>=;t--)
{
for(int i=;i<n;i++) if(t>=itm[gp][i].w)
{
//printf("t:%d w:%d\n",t,itm[gp][i].w);
dp[t] = max(dp[t],dp[t-itm[gp][i].w] + itm[gp][i].v);
}
}
//for(int i=0;i<T;i++)
//printf("%d ",dp[i]);
//printf("\n");
} printf("Case %d: %d\n",cas++,dp[T]);
}
}

HDU4341-Gold miner-分组DP的更多相关文章

  1. HDU-4341 Gold miner 题解

    题目大意 黄金矿工的游戏,不过每个金块可以看做是质点,没有大小,给出每个金块的坐标.抓取所花费的时间(包括返回的时间),以及价值,其中有一些金块可能会共线.求在规定时间内所获得的最大价值. 样例 样例 ...

  2. HDU 4341 Gold miner(分组背包)

    题目链接 Gold miner 目标是要在规定时间内获得的价值总和要尽可能大. 我们先用并查集把斜率相同的物品分在同一个组. 这些组里的物品按照y坐标的大小升序排序. 如果组内的一个物品被选取了,那该 ...

  3. 2012 #5 Gold miner

    Gold miner Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  4. 【HDU - 4341】Gold miner(分组背包)

    BUPT2017 wintertraining(15) #8B 题意 给出每个黄金的坐标.价值及耗时,同一方向的黄金只能依次取,求T时间内收获的最大值. 题解 同一方向,物品前缀和构成的组合,相当于是 ...

  5. HDU 4341 Gold miner (分组背包)

    先把线按照距离原点的距离排序,然后用叉积把在同一条直线上的点放在一起, 把在同一条线上的点中的前i个点当成一个点就转化成了分组背包. 写if(kas++) putchar('\n') 居然PE了,PE ...

  6. 01背包(分组) HDOJ 4341 Gold miner

    题目传送门 题意:有n个金矿,每个金矿有抓取的消耗的时间和价值,矿工在原点,问在T时间内能得到的最大的价值 分析:唯一和01背包不同的是金矿可能共线,也就是抓取近的金矿后才能抓后面共线的金矿.这是分组 ...

  7. HDU 1712 裸分组dp

    http://acm.hdu.edu.cn/showproblem.php?pid=1712 N门课M天复习,第i门课花费j天获得的效益是dp[i][j] 求最大效益 分组背包,同一门课不能选两次 三 ...

  8. BZOJ 1296: [SCOI2009]粉刷匠 分组DP

    1296: [SCOI2009]粉刷匠 Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上 ...

  9. 【HDOJ】4341 Gold miner

    分组01背包.在一条直线上的点归为一组. /* 4341 */ #include <iostream> #include <sstream> #include <stri ...

  10. LightOj:1030-Discovering Gold(期望dp模板)

    传送门:http://www.lightoj.com/volume_showproblem.php?problem=1030 Discovering Gold Time Limit: 2 second ...

随机推荐

  1. Dapper简易教程(翻译自Github上StackExchange/Dapper)

    本文源自:https://github.com/cnxy/Dapper-zh-cn 本博客作者与Github上作者(cnxy)实为同一个作者.由于笔者翻译水平有限,文本中错误难免,欢迎指正! 本文翻译 ...

  2. WebApi集成Swagger

    1.新建一个WebApi空项目 2.新建一个Person实体类: public class Person { public int ID { get; set; } public string Use ...

  3. 小L的项链切割 (回文串)

    题目描述 小T送给了小L了一串项链.为了方便,我们把项链上形态不同钻石用不同的字母表示.这样小L的项链就变成了一个字符串.小L忽然想把这串项链优美地切割一下,她想把它切割成尽量少的回文项链,啊也就是回 ...

  4. 多项式求值 n维多项式 Horner解法

    #include<iostream> using namespace std; template<class T> T ploy(T *coeff,int n,const T& ...

  5. PS滤镜制作下雨照片特效

    原图 一.打开你想要添加下雨效果的照片,并新建一个图层,命名为雨,填充为黑色,对“雨”层执行:滤镜 > 杂色> 添加杂色,参数如图. 二.对“雨”层执行:滤镜 > 模糊 > 高 ...

  6. Java面试题详解一:面向对象三大特性

    一,多态:1.面向对象四大基本特性:抽象,封装,继承,多态抽象,封装,继承是多态的基础.多态是抽象,封装,继承的表现.2.什么是多态不同类的对象对同一消息作出不同的响应叫做多态3.多态的作用简单来说: ...

  7. Linux系统mysql使用(一)

    一.安装 sudo apt-get update #更新软件源 sudo apt-get install mysql-server #安装mysql 二.启动和关闭 service mysql sta ...

  8. 给input标签添加默认提示文字

    <input name="username" placeholder="请输入用户名" /> placeholder = "提示文字&qu ...

  9. React Native之TextInput的介绍与使用(富文本封装与使用实例,常用输入框封装与使用实例)

    React Native之TextInput的介绍与使用(富文本封装与使用实例,常用输入框封装与使用实例) TextInput组件介绍 TextInput是一个允许用户在应用中通过键盘输入文本的基本组 ...

  10. pl/sql实现打印九九乘法表

    学习PL/SQL循环的时候写的,记录一下. declare v_number1 ); -- 外层循环变量 v_number2 ); -- 内层循环变量 begin .. -- 开始外层循环 loop ...