HDU4341-Gold miner-分组DP
模拟黄金矿工这个游戏,给出每一个金子的位置和所需时间,计算在给定时间内最大收益。
刚看这道题以为金子的位置没什么用,直接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的更多相关文章
- HDU-4341 Gold miner 题解
题目大意 黄金矿工的游戏,不过每个金块可以看做是质点,没有大小,给出每个金块的坐标.抓取所花费的时间(包括返回的时间),以及价值,其中有一些金块可能会共线.求在规定时间内所获得的最大价值. 样例 样例 ...
- HDU 4341 Gold miner(分组背包)
题目链接 Gold miner 目标是要在规定时间内获得的价值总和要尽可能大. 我们先用并查集把斜率相同的物品分在同一个组. 这些组里的物品按照y坐标的大小升序排序. 如果组内的一个物品被选取了,那该 ...
- 2012 #5 Gold miner
Gold miner Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 【HDU - 4341】Gold miner(分组背包)
BUPT2017 wintertraining(15) #8B 题意 给出每个黄金的坐标.价值及耗时,同一方向的黄金只能依次取,求T时间内收获的最大值. 题解 同一方向,物品前缀和构成的组合,相当于是 ...
- HDU 4341 Gold miner (分组背包)
先把线按照距离原点的距离排序,然后用叉积把在同一条直线上的点放在一起, 把在同一条线上的点中的前i个点当成一个点就转化成了分组背包. 写if(kas++) putchar('\n') 居然PE了,PE ...
- 01背包(分组) HDOJ 4341 Gold miner
题目传送门 题意:有n个金矿,每个金矿有抓取的消耗的时间和价值,矿工在原点,问在T时间内能得到的最大的价值 分析:唯一和01背包不同的是金矿可能共线,也就是抓取近的金矿后才能抓后面共线的金矿.这是分组 ...
- HDU 1712 裸分组dp
http://acm.hdu.edu.cn/showproblem.php?pid=1712 N门课M天复习,第i门课花费j天获得的效益是dp[i][j] 求最大效益 分组背包,同一门课不能选两次 三 ...
- BZOJ 1296: [SCOI2009]粉刷匠 分组DP
1296: [SCOI2009]粉刷匠 Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上 ...
- 【HDOJ】4341 Gold miner
分组01背包.在一条直线上的点归为一组. /* 4341 */ #include <iostream> #include <sstream> #include <stri ...
- LightOj:1030-Discovering Gold(期望dp模板)
传送门:http://www.lightoj.com/volume_showproblem.php?problem=1030 Discovering Gold Time Limit: 2 second ...
随机推荐
- Python股票分析系列——基础股票数据操作(一).p3
该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第3部分.在本教程中,我们将使用我们的股票数据进一步分解一些基本的数据操作和可视化.我们将要使用 ...
- java.util.Stack类中 empty() 和 isEmpty() 方法的作用
最近在学习算法和数据结构,用到Java里的Stack类,但程序运行结果一直和我预料的不一样,网上也没查清楚,最后查了API,才搞明白. java.util.Stack继承类 java.util.Vec ...
- 个人实战演练全过程——No.1 最大连续子数组求和
之前的一次个人总结和一次单元测试入门学习是开启软件工程课程的前奏曲,也是热身,现在大家对于这门课程也有了初步的了解和认识,这次要开始真正的演奏了,要从头到尾完全靠自己的能力来解决一个问题,进行实战演练 ...
- Kickstart Practice Round 2017---A
Problem The Constitution of a certain country states that the leader is the person with the name con ...
- springmvc的@ResponseBody报错
错误:差不多就是下面的格式 原因:你可能返回的类型是这样的List<School>而school类中可能包含Class类或者Teacher类,就是包含对象. 这样的话jackson是不能帮 ...
- DAG路径覆盖模型
概述 路径覆盖模型的特点是DAG中每个点经过且只经过一次,且一条路径覆盖路径上的所有点. 将每个点拆为\(x\)和\(x'\),暂不考虑其实际意义.然后连边\(S\rightarrow x\),\(x ...
- POJ - 2528 区间离散化,线段树区间修改,区间询问
这个题非常有意思的地方是,我们发现区间[1,4]和[5,8]是紧挨着的,因为这个的数代表的是一段区间,原本我们对于普通的离散, a[1]=1,a[2]=5,a[3]=6,a[4]=8;数组下标就是重新 ...
- PT与PX区别
字体大小的设置单位,常用的有2种:px.pt.这两个有什么区别呢? 先搞清基本概念:px就是表示pixel,像素,是屏幕上显示数据的最基本的点: pt就是point,是印刷行业常用单位,等于1/72英 ...
- 斐波那契数列yield表示
def fib(num): n=0 a,b=0,1 while n<num: print(b) yield a,b=b,a+b n=n+1a=fib(30)next(a)next(a)
- storm问题汇总
1.删除了本地topology导致无法启动nimbus 删除storm的自定义的库中的数据 删除zookeeper中配置的dataDir中的数据 重启服务即可