hdu 3810 Magina 队列模拟0-1背包
题意:
出一些独立的陆地,每片陆地上有非常多怪物。杀掉每一个怪物都须要一定的时间,并能获得一定的金钱。给出指定的金钱m, 求最少要多少时间能够得到m金钱,仅能选择一个陆地进行杀怪。
题解:
这题,假设无论数据范围,非常easy想到对每片陆地求一次0-1背包(dp(i, j) = min(dp(i-1, j), dp[i-1, j-money] + time), i 为金钱)。然后在全部陆地中找出最少的时间即为答案,可是这题的数据范围太大金钱m可达到1e9, 所以不能单纯的直接用数组模拟,考虑第i个怪物,要更新第i个怪物。仅仅须要知道两个状态,那就是dp[i-1][j],
和dp[i-1][j-money]。 所以。我们仅仅须要保存第i-1个怪物的所有合法状态,就能更新第i个怪物的状态。 所以我们能够考虑使用两个优先队列来维护上一轮的状态和这一轮的状态。就能找到答案了。首先,将两个队列都依照money从大到小。time从小到大的顺序排列,每次把q1所有出队列更新下一个状态,并把两个状态都放入q2中,然后从q2中选择最优解再拷贝到q1中,最后更新ans就可以。
代码:
- #include <cstdio>
- #include <cstring>
- #include <vector>
- #include <queue>
- #include <algorithm>
- using namespace std;
- typedef long long LL;
- typedef vector<int>::iterator Pointer;
- const int maxn = 60;
- const int inf = 1e9;
- vector<int> group[maxn];
- vector<int> mp[maxn];
- int n, m, gcnt;
- struct node
- {
- LL tm, val;
- node() {}
- node(LL tm, LL val) : tm(tm), val(val) {}
- bool operator < (const node& tmp) const
- {
- return val < tmp.val || (val == tmp.val && tm > tmp.tm);
- }
- }arr[maxn], now, nxt;
- void init()
- {
- for (int i = 0; i < maxn; ++i) group[i].clear(), mp[i].clear();
- }
- bool vis[maxn];
- void dfs(int u)
- {
- group[gcnt].push_back(u);
- vis[u] = true;
- for (Pointer it = mp[u].begin(); it != mp[u].end(); ++it)
- {
- int v = *it;
- if (!vis[v])
- {
- dfs(v);
- }
- }
- }
- void divide_group()
- {
- memset(vis, false, sizeof vis);
- gcnt = 0;
- for (int i = 1; i <= n; i++)
- {
- if (!vis[i])
- {
- dfs(i);
- gcnt++;
- }
- }
- }
- priority_queue<node> q1, q2;
- inline void clear_queue()
- {
- while (!q1.empty())
- {
- q1.pop();
- }
- while (!q2.empty())
- {
- q2.pop();
- }
- }
- LL mint;
- void zeroOnePack(int team)
- {
- for (Pointer it = group[team].begin(); it != group[team].end(); ++it)
- {
- int v = *it;
- while (!q1.empty())
- {
- now = q1.top(), q1.pop();
- q2.push(now);
- nxt = node(now.tm+arr[v].tm, now.val+arr[v].val);
- if (nxt.val >= m && nxt.tm < mint)
- {
- mint = nxt.tm; continue;
- }
- if (nxt.tm >= mint) continue;
- q2.push(nxt);
- }
- LL pre = inf;
- while (!q2.empty())
- {
- node tmp = q2.top(); q2.pop();
- if (tmp.tm < pre)
- {
- pre = tmp.tm;
- q1.push(tmp);
- }
- }
- }
- }
- LL solve()
- {
- mint = inf;
- for (int i = 0; i < gcnt; i++)
- {
- now = node(0, 0);
- clear_queue();
- q1.push(now);
- zeroOnePack(i);
- }
- return mint == inf ?
- -1 : mint;
- }
- int main()
- {
- // freopen("/Users/apple/Desktop/in.txt", "r", stdin);
- int t, kase = 0; scanf("%d", &t);
- while (t--)
- {
- scanf("%d%d", &n, &m);
- init();
- for (int i = 1; i <= n; i++)
- {
- int k; scanf("%lld%lld%d", &arr[i].tm, &arr[i].val, &k);
- for (int j = 0; j < k; j++)
- {
- int v; scanf("%d", &v);
- mp[i].push_back(v);
- }
- }
- divide_group();
- LL ans = solve();
- printf("Case %d: ", ++kase);
- if (ans == -1)
- {
- printf("Poor Magina, you can't save the world all the time!\n");
- }
- else
- {
- printf("%lld\n", ans);
- }
- }
- return 0;
- }
hdu 3810 Magina 队列模拟0-1背包的更多相关文章
- 【HDU 3810】 Magina (01背包,优先队列优化,并查集)
Magina Problem Description Magina, also known as Anti-Mage, is a very cool hero in DotA (Defense of ...
- HDU 2159 FATE(二维费用背包)
FATE Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- HDU 1712 ACboy needs your help(包背包)
HDU 1712 ACboy needs your help(包背包) pid=1712">http://acm.hdu.edu.cn/showproblem.php? pid=171 ...
- python--递归(附利用栈和队列模拟递归)
博客地址:http://www.cnblogs.com/yudanqu/ 一.递归 递归调用:一个函数,调用的自身,称为递归调用 递归函数:一个可以调用自身的函数称为递归函数 凡是循环能干的事,递归都 ...
- HDU 3507 单调队列 斜率优化
斜率优化的模板题 给出n个数以及M,你可以将这些数划分成几个区间,每个区间的值是里面数的和的平方+M,问所有区间值总和最小是多少. 如果不考虑平方,那么我们显然可以使用队列维护单调性,优化DP的线性方 ...
- HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包)
HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包) 题意分析 裸的完全背包问题 代码总览 #include <iostream> #include <cstdio> ...
- HDU 3591 The trouble of Xiaoqian(多重背包+全然背包)
HDU 3591 The trouble of Xiaoqian(多重背包+全然背包) pid=3591">http://acm.hdu.edu.cn/showproblem.php? ...
- PTA 银行排队问题之单队列多窗口加VIP服务 队列+模拟
假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选择时,假设顾客总是选择编号最小的窗口. 有些银行会给 ...
- 原生JS实现队结构及利用队列模拟‘击鼓传花’游戏
1. 前言 队列,是一种遵从先进先出(FIFO,First-In-First-Out)原则的有序集合.队列在尾部添加新元素,并从顶部移除元素,最新添加的元素必须排在队列的末尾. 2.功能说明 enqu ...
随机推荐
- 【BZOJ3294/洛谷3158】[CQOI2011]放棋子(组合数+DP)
题目: 洛谷3158 分析: 某OIer兔崽子的此题代码中的三个函数名:dfs.ddfs.dddfs(充满毒瘤的气息 显然,行与行之间.列与列之间是互相独立的.考虑背包,用\(f[k][i][j]\) ...
- javascript特殊值常量
Infinity 表示无穷大的特殊值.当数字运算结果超出javascript能表示的数字范围时. Nan 特殊的非数字值(not a number).0除0.数字运算符的操作数为字符等情况. Numb ...
- HTML 网页创建
最简单的方式就是创建一个文本文档,然后将.txt后缀改为.html或者htm. 完成上面的步骤会创建一个完全空白的网页,下面填充一点内容,代码实例如下: <!DOCTYPE html> & ...
- Leetcode0523--Continuous Subarray Sum 连续和倍数
[转载请注明]https://www.cnblogs.com/igoslly/p/9341666.html class Solution { public: bool checkSubarraySum ...
- SQL Server 中4个系统数据库,Master、Model、Msdb、Tempdb。
(1)Master数据库是SQL Server系统最重要的数据库,它记录了SQL Server系统的所有系统信息.这些系统信息包括所有的登录信息.系统设置信息.SQL Server的初始化信息和其他系 ...
- 4th 循环结构概述和for语句的格式及其使用
04.01_Java语言基础(循环结构概述和for语句的格式及其使用) A:循环结构的分类 for,while,do...while B:循环结构for语句的格式: for(初始化表达式;条件表达式; ...
- Git 分支创建
分支策略:git上始终保持两个分支,master分支与develop分支.master分支主要用于发布时使用,而develop分支主要用于开发使用. 创建master的分支developgit che ...
- Win32编程笔记
我都决定了目前不再接触这些个浪费精力的API了,结果为了DirectX编程我特么又回来了.....微软你的东西真是坑人 以前用这玩意的时候需要什么就查,查完就忘了,这次记一记,以后再用也不至于忘的太离 ...
- (转)Hibernate的优化方案
http://blog.csdn.net/yerenyuan_pku/article/details/70768603 HQL优化 使用参数绑定 使用绑定参数的原因是让数据库一次解析SQL,对后续的 ...
- android Adapter总结
1.连接视图与数据.数据封装: 2.视图构造与配置: 3.数据更新监听: 4.视图重用机制. * An Adapter object acts as a bridge between an {@lin ...