HDU-3810 超大容量01背包
题意:有n堆野兽,每堆野兽屠杀完完需要花费ti时间,可以增加金钱gi,敌法师有瞬移技能,可以从某堆野兽移到另一堆野兽,题目有给定从哪堆可以移到哪堆。最后问在满足打的金钱多余m的情况下的最少时间。数据范围:1 <= T <= 50 , 1 <= N <= 50(怪物数量), 1 <= Ti <= 10000000(时间),1 <= M, Gi <= 1000000000(要求金钱/每组野怪金钱)。
解法:题解参考https://www.cnblogs.com/Konjakmoyu/p/5962062.html?utm_source=itdadao&utm_medium=referral。这位大佬的。
看到题目很明显的0/1背包,但是看到数据范围发现是个超大容量的01背包,那么我们就肯定不能使用DP来解决这个问题了。我们注意到虽然容量很大但是物品数量却非常小,暗示我们可以用一些比较暴力一些的办法。我们想办法用别的数据结构模拟解01背包的过程,于是就用到 优先队列模拟01背包做DP(为什么要用优先队列,下面会讲到)。
假定用q0队列表示上一行,q1队列表示当前行。那么对于当前物品i,我们就从上一行状态q0转移到q1,那么也就是枚举q0的每个状态然后对物品i有两种选择:选或者不选,想起来很简单。可惜这样会获得MLE/TLE。为什么?因为每次都选和不选就相当于暴搜了,时间复杂度是2^50次方肯定不行。我们得剪枝,最关键的是其实同一时间的状态有很多都是没有用的,钱比别人少时间却还比别人多,这样的状态没有用!!!于是我们要用到优先队列,金钱多的排前面然后同样多钱的时间少的排前面,那么我们筛选本次拓展出来的状态哪些是有用的?因为我们优先队列已经是按金钱多排前面,所以此时时间单调减的状态才有用!!!
于是加上上面这个大剪枝时候我们再加些容易想到的小细节就可以获得AC了。
细节详见代码:
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int N=;
const int INF=0x7fffffff;
int n,m,k,w[N],v[N],fa[N];
struct dat{
int x,y; //时间,金钱
bool operator < (const dat &rhs) const {
return y<rhs.y || y==rhs.y && x>rhs.x;
}
};
priority_queue<dat> q1,q2; int getfa(int x) { return x==fa[x] ? x : fa[x]=getfa(fa[x]); } int main()
{
int T,kase=; scanf("%d",&T);
while (T--) {
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) fa[i]=i;
for (int i=;i<=n;i++) {
scanf("%d%d%d",&w[i],&v[i],&k);
for (int j=;j<=k;j++) {
int x; scanf("%d",&x);
fa[getfa(x)]=getfa(i);
}
} int ans=INF;
for (int i=;i<=n;i++)
if (getfa(i)==i) { //一个联通块的物品
while (!q1.empty()) q1.pop();
while (!q2.empty()) q2.pop();
q1.push((dat){,});
for (int j=;j<=n;j++) { //j个物品
if (getfa(j)!=i) continue;
while (!q1.empty()) {
dat u=q1.top(); q1.pop();
if (u.y>=m) { ans=min(ans,u.x); continue; } //剪枝1
if (u.x>=ans) continue; //剪枝2
q2.push(u); //不选
int x=u.x+w[j],y=u.y+v[j];
if (y>=m) { ans=min(ans,x); continue; } //剪枝1
if (x>=ans) continue; //剪枝2
q2.push((dat){x,y}); //选
}
int Min=INF;
while (!q2.empty()) {
dat u=q2.top(); q2.pop();
if (u.x<Min) q1.push(u),Min=u.x; //剪枝3:钱比别人少时间却还比别人多,这样的状态没有用
}
}
}
if (ans==INF) printf("Case %d: Poor Magina, you can't save the world all the time!\n",++kase);
else printf("Case %d: %d\n",++kase,ans);
}
return ;
}
HDU-3810 超大容量01背包的更多相关文章
- hdu 2546 典型01背包
分析:每种菜仅仅可以购买一次,但是低于5元不可消费,求剩余金额的最小值问题..其实也就是最接近5元(>=5)时, 购买还没有买过的蔡中最大值问题,当然还有一些临界情况 1.当余额充足时,可以随意 ...
- ACM HDU Bone Collector 01背包
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 这是做的第一道01背包的题目.题目的大意是有n个物品,体积为v的背包.不断的放入物品,当然物品有 ...
- hdu 2955 Robberies (01背包)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955 思路:一开始看急了,以为概率是直接相加的,wa了无数发,这道题目给的是被抓的概率,我们应该先求出总的 ...
- HDU 2639(01背包求第K大值)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2639 Bone Collector II Time Limit: 5000/2000 MS (Jav ...
- hdu 3466 排序01背包
也是好题,带限制的01背包,先排序,再背包 这题因为涉及到q,所以不能直接就01背包了.因为如果一个物品是5 9,一个物品是5 6,对第一个进行背包的时候只有dp[9],dp[10],…,dp[m], ...
- hdu 2955 Robberies 0-1背包/概率初始化
/*Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- HDU 2639 (01背包第k优解)
/* 01背包第k优解问题 f[i][j][k] 前i个物品体积为j的第k优解 对于每次的ij状态 记下之前的两种状态 i-1 j-w[i] (选i) i-1 j (不选i) 分别k个 然后归并排序并 ...
- HDU——2955 Robberies (0-1背包)
题意:有N个银行,每抢一个银行,可以获得\(v_i\)的前,但是会有\(p_i\)的概率被抓.现在要把被抓概率控制在\(P\)之下,求最多能抢到多少钱. 分析:0-1背包的变形,把重量变成了概率,因为 ...
- HDU 1171Big Event in HDU(转01背包)
题意: 给你一组数,分成差距最小的两份A,B(A>=B) 分析: 转01背包 注意: 01背包用一维数组 不要用二维 二维数组若是开太大,内存超限,开太小,RE #include "c ...
随机推荐
- 3D Computer Grapihcs Using OpenGL - 02 QGLWidget
用红色来填充GLWidget窗口 修改MyGlWindow.h,添加两个函数,一个用来初始化OpengGL,一个用来绘制OpenGL #pragma once #include <QtOpenG ...
- SpringCloud 教程 (六)断路器聚合监控(Hystrix Turbine)
一.Hystrix Turbine简介 看单个的Hystrix Dashboard的数据并没有什么多大的价值,要想看这个系统的Hystrix Dashboard数据就需要用到Hystrix Turbi ...
- K-th occurrence HDU - 6704 (后缀数组+二分线段树+主席树)
大意: 给定串s, q个询问(l,r,k), 求子串s[l,r]的第kk次出现位置. 这是一篇很好的题解: https://blog.csdn.net/sdauguanweihong/article/ ...
- ora600
4节点RAC:版本oracle11.2.0.4 22:20——23:40发生ora600 alert日志: Errors in file /u01/app/oracle/diag/rdbms/orcl ...
- (三)Maven之仓库
目录 引言:坐标和依赖是一个构件在Maven世界中逻辑表示方式,而构件的物理表示方式就是文件而已,仓库就是统一管理这些文件的地方. 目录 仓库类别 本地仓库 远程仓库: 中仓仓库(自带的默认远程仓库) ...
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_08 转换流_2_编码引出的问题_FileReader读取GBK格式文件
IDEA默认的编码格式是UTF-8 新建一个txt文件.输入你好 ANSI就是系统默认编码.保存即可. 通过IDE打开是乱码的,因为默认打开的方式是UTF-8 转换为char类型 输出了乱码
- 阿里云SLB产品HTTP、HTTPS、UDP协议使用
1.http协议测试 第一步:添加http监听服务,前端端口为8080,后端端口为80,健康检查中检查端口为后端端口80: 第二步:在绑定的服务器上安装服务,步骤如下 centos系统中启动http协 ...
- 【ABAP系列】SAP ABAP中使用for all entries in小结
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP中使用for a ...
- LeetCode——707 设计链表
题目: 总而言之就是要用C++手撸链表,我的代码: class MyLinkedList { public: /** Initialize your data structure here. */ M ...
- 个人对BFC的见解
BFC:块级格式化上下文,它是指一个独立的块级渲染区域,只有Block-level BOX参与,该区域拥有一套渲染规则来约束块级盒子的布局,且与区域外部无关. BFC的生成 既然上文提到BFC是一块渲 ...