题意:

出一些独立的陆地,每片陆地上有非常多怪物。杀掉每一个怪物都须要一定的时间,并能获得一定的金钱。给出指定的金钱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背包的更多相关文章

  1. 【HDU 3810】 Magina (01背包,优先队列优化,并查集)

    Magina Problem Description Magina, also known as Anti-Mage, is a very cool hero in DotA (Defense of ...

  2. HDU 2159 FATE(二维费用背包)

    FATE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  3. HDU 1712 ACboy needs your help(包背包)

    HDU 1712 ACboy needs your help(包背包) pid=1712">http://acm.hdu.edu.cn/showproblem.php? pid=171 ...

  4. python--递归(附利用栈和队列模拟递归)

    博客地址:http://www.cnblogs.com/yudanqu/ 一.递归 递归调用:一个函数,调用的自身,称为递归调用 递归函数:一个可以调用自身的函数称为递归函数 凡是循环能干的事,递归都 ...

  5. HDU 3507 单调队列 斜率优化

    斜率优化的模板题 给出n个数以及M,你可以将这些数划分成几个区间,每个区间的值是里面数的和的平方+M,问所有区间值总和最小是多少. 如果不考虑平方,那么我们显然可以使用队列维护单调性,优化DP的线性方 ...

  6. HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包)

    HDOJ(HDU).1284 钱币兑换问题 (DP 完全背包) 题意分析 裸的完全背包问题 代码总览 #include <iostream> #include <cstdio> ...

  7. HDU 3591 The trouble of Xiaoqian(多重背包+全然背包)

    HDU 3591 The trouble of Xiaoqian(多重背包+全然背包) pid=3591">http://acm.hdu.edu.cn/showproblem.php? ...

  8. PTA 银行排队问题之单队列多窗口加VIP服务 队列+模拟

    假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选择时,假设顾客总是选择编号最小的窗口. 有些银行会给 ...

  9. 原生JS实现队结构及利用队列模拟‘击鼓传花’游戏

    1. 前言 队列,是一种遵从先进先出(FIFO,First-In-First-Out)原则的有序集合.队列在尾部添加新元素,并从顶部移除元素,最新添加的元素必须排在队列的末尾. 2.功能说明 enqu ...

随机推荐

  1. scrapy的UA池和代理池

    一.下载中间件(Downloader Middlewares) 框架图如下 下载中间件(Downloader Middlewares)位于scrapy引擎和下载器之间的一层组件. - 作用: (1)引 ...

  2. ACM_小Z的A+B

    小Z的A+B Time Limit: 2000/1000ms (Java/Others) Problem Description: 小Z最喜欢A+B了,没事就研究研究,比如什么大整数A+B(就是100 ...

  3. mysql使用出现错误:mysqld dead but subsys locked

    现象: 登陆时候出现如下信息 [root@localhost home]# mysql -uroot -p123456mysql: [Warning] Using a password on the ...

  4. UNIX环境高级编程--3

    文件IO 函数lseek: 每个打开文件都有一个与其相关联的“当前文件偏移量”,用来度量从文件开始处计算的字节数.除非指定O_APPEND选项,否则该偏移量被置为0.如果文件描述符指向的是一个管道.F ...

  5. 实现一个类似于收趣APP的功能

    近日想做一个类似于收趣APP软件的一个功能,将头条.微信等其他App的文章能够通过分享微信好友的方式分享到自己的平台软件中. 分享的方式有三种: 1.通过微信好友的方式,将文章分享给收趣. 2.复制文 ...

  6. MVC系列学习(十二)-服务端的验证

    在前一讲,提到过,客户端的东西永远可以造假,所以我们还要在服务端进行验证 注意:先加载表单,后添加js文件,才能有效:而先加载js,后添加表单,是没有效果的 1.视图与Model中的代码如下 2.一张 ...

  7. Python随笔-函数

    在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回. def GetMax(v1, v2):#注 ...

  8. [ NOIP 2008 ] TG

    \(\\\) \(\#A\) \(Word\) 给出一个长为\(N\)的小写字母串,判断出现所有字母中最多出现次数减最少出现次数得到的答案是否是质数. \(N\in [1,100]\) 直接按题意开桶 ...

  9. 控制台——屏蔽Ctrl+C快捷键对窗体的关闭功能

    导入SetCtrlHandlerHandler API //定义处理程序委托 public delegate bool ConsoleCtrlDelegate(int ctrlType); //导入S ...

  10. 6、scala Map和Tuple

    1.  创建Map 2.访问Map元素 3.修改Map元素的值 4.遍历Map 5.SortedMap和LinkedHashMap 6.Map的元素类型Tuple 1.  创建Map 创建不可变的Ma ...