博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj3875 [Ahoi2014&Jsoi2014]骑士游戏
阅读量:5024 次
发布时间:2019-06-12

本文共 2205 字,大约阅读时间需要 7 分钟。

Description

长期的宅男生活中, \(JYY\) 又挖掘出了一款 \(RPG\) 游戏。在这个游戏中 \(JYY\) 会扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽。

在这个游戏中, \(JYY\) 一共有两种攻击方式,一种是普通攻击,一种是fa术攻击。两种攻击方式都会消耗 \(JYY\) 一些体力。采用普通攻击进攻怪兽并不能把怪兽彻底杀死,怪兽的尸体可以变出其他一些新的怪兽,注意一个怪兽可能经过若干次普通攻击后变回一个或更多同样的怪兽;而采用法术攻击则可以彻底将一个怪兽杀死。当然了,一般来说,相比普通攻击,法术攻击会消耗更多的体力值(但由于游戏系统 \(bug\),并不保证这一点)。
游戏世界中一共有 \(N\) 种不同的怪兽,分别由 \(1\)\(N\) 编号,现在 \(1\) 号怪兽入侵村庄了, \(JYY\) 想知道,最少花费多少体力值才能将所有村庄中的怪兽全部杀死呢?

Input

第一行包含一个整数 \(N\)

接下来 \(N\) 行,每行描述一个怪兽的信息;
其中第 \(i\) 行包含若干个整数,前三个整数为 \(S_i,K_i,R_i\) ,表示对于 \(i\) 号怪兽,普通攻击需要消耗 \(S_i\) 的体力,法术攻击需要消耗 \(K_i\) 的体力,同时 \(i\) 号怪兽死亡后会产生 \(R_i\) 个新的怪兽。表示一个新出现的怪兽编号。同一编号的怪兽可以出现多个。

Output

输出一行一个整数,表示最少需要的体力值。

Sample Input

4

4 27 3 2 3 2
3 5 1 2
1 13 2 4 2
5 6 1 2

Sample Output

26

HINT

首先用消耗 \(4\) 点体力用普通攻击,然后出现的怪兽编号是 \(2\)\(2\)\(3\) 。花费 \(10\) 点体力用法术攻击杀死两个编号为 \(2\) 的怪兽。剩下 \(3\) 号怪兽花费 \(1\) 点体力进行普通攻击。此时村庄里的怪兽编号是 \(2\)\(4\) 。最后花费 \(11\) 点体力用法术攻击将这两只怪兽彻底杀死。一共花费的体力是 \(4+5+5+1+5+6=26\)

\(2\le N\le 2\times 10^5,1<=R_i,\sum {R_i} \le 10^6,1\le K_i,S_i\le 5\times 10^{14}\)

Solution

\(spfa\) 来进行 \(dp\) 。其中

  • \(d[i]\) 表示清除 \(i\) 以及后面的所有怪兽的最小费用。
  • \(d[1]\) 为答案。

直接 \(dp\) 的话有后效性,所以用 \(spfa\)\(dp\) ,建一个反图来更新前驱。

#include
using namespace std;#define N 200001#define rep(i, a, b) for (int i = a; i <= b; i++)#define fech(i, x) for (int i = 0; i < x.size(); i++)#define ll long longinline ll read() { ll x = 0, flag = 1; char ch = getchar(); while (!isdigit(ch)) { if (!(ch ^ '-')) flag = -1; ch = getchar(); } while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); return x * flag;}int n;ll s[N], d[N];vector
g[N], r[N];queue
q; bool inq[N];void spfa() { rep(i, 1, n) q.push(i), inq[i] = 1; while(!q.empty()) { int u = q.front(); ll t = s[u]; q.pop(), inq[u] = 0; fech(i, g[u]) t += d[g[u][i]]; if(t < d[u]) { d[u] = t; int v; fech(i, r[u]) if(!inq[(v = r[u][i])]) q.push(v), inq[v] = 1; } } cout << d[1];}int main() { n = read(); rep(i, 1, n) { s[i] = read(), d[i] = read(); int T = read(); while(T--) { int t = read(); g[i].push_back(t), r[t].push_back(i); } } spfa(); return 0;}

转载于:https://www.cnblogs.com/aziint/p/8416376.html

你可能感兴趣的文章
Android中获取应用程序(包)的大小-----PackageManager的使用(二)
查看>>
Codeforces Gym 100513M M. Variable Shadowing 暴力
查看>>
浅谈 Mybatis中的 ${ } 和 #{ }的区别
查看>>
CNN 笔记
查看>>
版本更新
查看>>
SQL 单引号转义
查看>>
start
查看>>
实现手机扫描二维码页面登录,类似web微信-第三篇,手机客户端
查看>>
PHP socket客户端长连接
查看>>
7、shell函数
查看>>
【转】Apache Jmeter发送post请求
查看>>
Nginx 基本 安装..
查看>>
【凸优化】保留凸性的几个方式(交集、仿射变换、投影、线性分式变换)
查看>>
NYOJ-613//HDU-1176-免费馅饼,数字三角形的兄弟~~
查看>>
TFS --- GrantBackup Plan Permissions Error
查看>>
傅里叶级数与积分方程
查看>>
软工作业3:用户体验分析——以“南通大学教务管理系统微信公众号”为例
查看>>
Css:背景色透明,内容不透明之终极方法!兼容所有浏览器
查看>>
我们前端跟后端是怎么合作的
查看>>
mysql存储过程
查看>>