BZOJ3875--骑士游戏(SPFA处理带后效性的动态规划)
3875: [Ahoi2014]骑士游戏
Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 181 Solved: 91
[Submit][Status][Discuss]
Description
【故事背景】
长期的宅男生活中,JYY又挖掘出了一款RPG游戏。在这个游戏中JYY会
扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽。
【问题描述】
在这个游戏中,JYY一共有两种攻击方式,一种是普通攻击,一种是法术攻
击。两种攻击方式都会消耗JYY一些体力。采用普通攻击进攻怪兽并不能把怪兽彻底杀死,怪兽的尸体可以变出其他一些新的怪兽,注意一个怪兽可能经过若干次普通攻击后变回一个或更多同样的怪兽;而采用法术攻击则可以彻底将一个怪兽杀死。当然了,一般来说,相比普通攻击,法术攻击会消耗更多的体力值(但由于游戏系统bug,并不保证这一点)。
游戏世界中一共有N种不同的怪兽,分别由1到N编号,现在1号怪兽入
侵村庄了,JYY想知道,最少花费多少体力值才能将所有村庄中的怪兽全部杀死呢?
Input
第一行包含一个整数N。
接下来N行,每行描述一个怪兽的信息;
其中第i行包含若干个整数,前三个整数为Si,Ki和Ri,表示对于i号怪兽,
普通攻击需要消耗Si的体力,法术攻击需要消耗Ki的体力,同时i号怪兽死亡后会产生Ri个新的怪兽。表示一个新出现的怪兽编号。同一编号的怪兽可以出现多个。
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<=N<=2*10^5,1<=Ri,Sigma(Ri)<=10^6,1<=Ki,Si<=5*10^14
分析:
首先要明白,SPFA用到了动态逼近(动态规划?)的思想,但它的动态是有后效性的,即一个点出队后,其最短路的值并未完全确定,可能后面还会对它进行松弛再次入队
这个题目其实是可以写出状态转移方程的:
令f[i]为杀死i号怪物的最小花销,则
f[i]=min(k[i],s[i]+Σf[j])
其中j为i用普通攻击后可以分裂为的怪物 ,k[i]为使用法术攻击,s[i]为使用普通攻击
要求杀死1号怪物的最小花费,最终结果即为f[1]
但是直接DP有后效性(状态之间相互依赖,并不是单向依赖),因此我们用SPFA来跑这个DP即可
初始时要把所有点入队,因为它们都可能被更新。
下面的代码中建立了两个邻接表,分别记录某个点的父亲与儿子(e[]与E[]),方便spfa
1 #include <queue>
2 #include <cstdio>
3 #include <cstring>
4 #include <iostream>
5 #include <algorithm>
6 #define N 201000
7 #define M 2010000
8 #define inf 0x3f3f3f3f
9 using namespace std;
10 struct KSD
11 {
12 int v,next;
13 }e[M],E[M];
14 int head[N],HEAD[N],cnt;
15 inline void add(int u,int v)
16 {
17 e[++cnt].v=v;
18 E[cnt].v=u;
19 e[cnt].next=head[u];
20 E[cnt].next=HEAD[v];
21 HEAD[v]=head[u]=cnt;
22
23 }
24 long long A[N],dist[N];
25 bool in[N];
26 int n;
27 queue<int>q;
28 void spfa()
29 {
30 while(!q.empty())q.pop();
31
32 int i,u,v;
33 for(i=1;i<=n;i++)q.push(i),in[i]=1;
34 while(!q.empty())
35 {
36 u=q.front(),q.pop(),in[u]=0;
37 long long temp=A[u];
38 for(i=head[u];i;i=e[i].next)
39 temp+=dist[e[i].v];
40 if(temp>=dist[u])continue;
41 dist[u]=temp;
42 for(i=HEAD[u];i;i=E[i].next)
43 if(!in[v=E[i].v])q.push(v),in[v]=1;
44 }
45 }
46 int main()
47 {
48 int i,j,k;
49 int a,b,c;
50 scanf("%d",&n);
51 for(i=1;i<=n;i++)
52 {
53 cin>>A[i]>>dist[i]>>c;
54 while(c--)
55 {
56 scanf("%d",&a);
57 add(i,a);
58 }
59 }
60 spfa();
61 cout<<dist[1];
62 return 0;
63 }
BZOJ3875--骑士游戏(SPFA处理带后效性的动态规划)的更多相关文章
- bzoj3875 【Ahoi2014】骑士游戏 spfa处理后效性动规
骑士游戏 [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽. [问题描述] 在这个游戏中,JYY一共有两种攻 ...
- 【BZOJ3875】【AHOI2014】骑士游戏 [Spfa][DP]
骑士游戏 Time Limit: 30 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 在这个游戏中,JYY一共有两种攻击 ...
- 【BZOJ3875】[Ahoi2014&Jsoi2014]骑士游戏 SPFA优化DP
[BZOJ3875][Ahoi2014&Jsoi2014]骑士游戏 Description [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会扮演一个英勇的 ...
- BZOJ 3875: [Ahoi2014]骑士游戏 spfa dp
3875: [Ahoi2014]骑士游戏 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3875 Description [故事背景] 长 ...
- bzoj 3875 骑士游戏 - spfa - 动态规划
Description [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽. [问题描述] 在这个游戏中,J ...
- LUOGU P4042 [AHOI2014/JSOI2014]骑士游戏 (spfa+dp)
传送门 解题思路 首先设\(f[x]\)表示消灭\(x\)的最小花费,那么转移方程就是 \(f[x]=min(f[x],\sum f[son[x]] +s[x])\),如果这个转移是一个有向无环图,那 ...
- luogu 4042 有后效性的dp
存在有后效性的dp,但转移方程 f[i] = min( f[i], s[i] + sigma f[j] ( j 是后效点) ) 每次建当前点和 转移点的边 e1, 某点和其会影响的点 e2 spfa ...
- 2019.01.22 bzoj3875: [Ahoi2014&Jsoi2014]骑士游戏(spfa+dp)
传送门 题意简述:nnn个怪物,对于编号为iii的怪物可以选择用aia_iai代价将其分裂成另外的bib_ibi个怪物或者用cic_ici代价直接消灭它,现在问消灭编号为1的怪物用的最小代价. ...
- BZOJ 3875: [Ahoi2014]骑士游戏 dp+spfa
题目链接: 题目 3875: [Ahoi2014]骑士游戏 Time Limit: 30 Sec Memory Limit: 256 MB 问题描述 [故事背景] 长期的宅男生活中,JYY又挖掘出了一 ...
随机推荐
- C++多线程基础学习笔记(二)
先总结延申以下前面(一)所讲的内容. 主线程从main()函数开始执行,我们创建的线程也需要一个函数作为入口开始执行,所以第一步先初始化函数. 整个进程是否执行完毕的标志是主线程是否执行完毕,一般情况 ...
- # 组合数学-组合数+lacus定理
目录 数论-组合数+lacus定理 组合数计算 lacus定理-大组合数取模 数论-组合数+lacus定理 组合数计算 为避免爆long long,\(20!\)就达到了long long 的范围,采 ...
- FFmpeg4.0笔记:VS2019编译FFmpeg4.0源码
0.下载TDM.msys和yasm 1.安装TDM-GCC-64 2.安装msys到TDM-GCC的安装目录中 3.将call "C:\Program Files (x86)\Microso ...
- Amoeba 实现MySQL读写分离
Amoeba是一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy,它集中地响应应用的请求,依据用户事先设置的规则,将SQL请求发送到特定的数据库上执行.基于此可以实现负载均衡. ...
- redis 学习(二)-- 通用命令
redis 学习(二)-- 通用命令 1. keys pattern 含义:查找所有符合给定模式(pattern)的key 命令 含义 keys * 遍历所有 key keys he[h-l]* 遍历 ...
- 优秀java博客
https://www.jianshu.com/p/efb58b7115bf?utm_source=tuicool https://www.nowcoder.com/discuss/110317 ht ...
- CentOS7搭建FastDFS V5.11分布式文件系统(三)
1.测试 前面两篇博文已对FastDFS的安装和配置,做了比较详细的讲解.FastDFS的基础模块都搭好了,现在开始测试下载. 1.1 配置客户端 同样的,需要修改客户端的配置文件: /etc/fdf ...
- 1.K近邻算法
(一)K近邻算法基础 K近邻(KNN)算法优点 思想极度简单 应用数学知识少(近乎为0) 效果好 可以解释机器学习算法使用过程中的很多细节问题 更完整的刻画机器学习应用的流程 图解K近邻算法 上图是以 ...
- tornada-模板
tornado模板 1.配置模板路径 (project/config.py) # coding=utf-8 import os BASE_DIRS = os.path.dirname(__file__ ...
- l洛谷P4779 【模板】单源最短路径(标准版)(dijkstra)
题目描述 给定一个 NN 个点,MM 条有向边的带非负权图,请你计算从 SS 出发,到每个点的距离. 数据保证你能从 SS 出发到任意点. 输入格式 第一行为三个正整数 N, M, SN,M,S. 第 ...