题意

Sol

这好像是我第一次接触三进制状压

首先,每次打完怪之后吃宝石不一定是最优的,因为有模仿怪的存在,可能你吃完宝石和他打就GG了。。

因此我们需要维护的状态有三个

0:没打

1:打了怪物 没吃宝石

2:打了怪物 吃了宝石

如果我们能知道打了那些怪,吃了那些宝石,那么此时的状态时确定的,预处理出来

然后DP就行了

mdzz这题卡常数

/*
首先打完怪之后吃宝石不一定是最优的
因此我们需要枚举出每个怪物的状态
0:没打
1:打了怪物 没吃宝石
2:打了怪物 吃了宝石
如果我们能知道打了那些怪,吃了那些宝石,那么此时的状态时确定的 */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<cmath>
//#define int long long
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<22, stdin), p1 == p2) ? EOF : *p1++)
char buf[( << )], *p1 = buf, *p2 = buf;
#define LL long long
using namespace std;
const int MAXN = * 1e6 + ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int T, N;
int lim, Hp, A, F, M, Mp[MAXN], IA[MAXN], IF[MAXN], IM[MAXN];//攻击 血量 防御 魔防
LL f[MAXN], Po[];
struct Enemy {
int H, A, D, S, ap, dp, mp, hp;
}a[];
vector<int> v[];
void init() {
memset(f, , sizeof(f));
Hp = read(); A = read(); F = read(); M = read();
N = read();
lim = Po[N];
for(int i = ; i <= N; i++) {
a[i].H = read(); a[i].A = read(); a[i].D = read(); a[i].S = read();
a[i].ap = read(); a[i].dp = read(); a[i].mp = read(); a[i].hp = read();
}
int K = read();
for(int i = ; i <= N; i++) v[i].clear();
for(int i = ; i <= K; i++) {
int u = read(), vv = read();
v[vv].push_back(u);
}
}
LL Attack(int sta, int id) {
LL Now = f[sta], A = IA[sta], D = IF[sta], M = IM[sta];
LL s = a[id].S, h = a[id].H, aa = a[id].A, d = a[id].D;
if (s & ) aa = A, d = D; // 模仿
if (s & ) D = ; // 无视防御
LL AA = max(0ll, A - d); // 勇士造成伤害
aa = max(0ll, aa - D) * (((s >> ) & ) + ); // 怪物造成的攻击力,是否连击
if (AA == ) return ;
LL t1 = (h - ) / AA + ; // 需要打怪几次
LL t2 = (s & ) ? (t1 * aa) : ((t1 - ) * aa); // 怪造成的攻击力,是否有先攻
LL t3 = max(0ll, t2 - M); // 减去魔防
return max(0ll, Now - t3);
}
void solve() {
f[] = Hp;
for(int sta = ; sta < lim; sta++) {
IA[sta] = A; IF[sta] = F; IM[sta] = M;
for(int i = ; i <= N; i++)
if(sta / Po[i - ] % == )
IA[sta] += a[i].ap, IF[sta] += a[i].dp, IM[sta] += a[i].mp;
}
for(int sta = ; sta < lim; sta++) {
if(f[sta] == ) continue;
for(int i = ; i <= N; i++) {
if(sta / Po[i - ] % == ) {// not kill
bool flag = ;
for(int j = ; j < v[i].size(); j++)
if(sta / Po[v[i][j] - ] % == ) // not kiil
{flag = ; break;}
if(flag == ) continue;
LL nhp = Attack(sta, i);
if(nhp > )
f[sta + Po[i - ]] = max(f[sta + Po[i - ]], nhp);
} else if(sta / Po[i - ] % == ) {
f[sta + Po[i - ]] = max(f[sta + Po[i - ]], f[sta] + a[i].hp);
}
}
}
printf("%lld\n", f[lim - ] == ? - : f[lim - ]);
}
main() {
Po[] = ;
for(int i = ; i <= ; i++) Po[i] = * Po[i - ];
T = read();
while(T--) {
init();
solve();
}
return ;
}
/*
2 2 1
1 1
2 1 1
*/

ZRDay6A. 萌新拆塔(三进制状压dp)的更多相关文章

  1. HDU 3001 三进制状压DP

    N个城市,M条道路,每条道路有其经过的代价,每一个城市最多能够到达两次,求走全然部城市最小代价,起点随意. 三进制状压.存储每一个状态下每一个城市经过的次数. 转移方程: dp[i+b[k]][k]= ...

  2. hdu 3001 Travelling 经过所有点(最多两次)的最短路径 三进制状压dp

    题目链接 题意 给定一个\(N\)个点的无向图,求从任意一个点出发,经过所有点的最短路径长度(每个点至多可以经过两次). 思路 状态表示.转移及大体思路 与 poj 3311 Hie with the ...

  3. Travelling (三进制+状压dp)

    题目链接 #include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read(){ ,f= ...

  4. HDU - 3001 Travelling(三进制状压dp)

    Travelling After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best ch ...

  5. UVA 10817 - Headmaster's Headache(三进制状压dp)

    题目:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=20&pag ...

  6. HDU 3001 三进制 状压dp

    Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  7. 三进制状压 HDOJ 3001 Travelling

    题目传送门 题意:从某个点出发,所有点都走过且最多走两次,问最小花费 分析:数据量这么小应该是状压题,旅行商TSP的变形.dp[st][i]表示状态st,在i点时的最小花费,用三进制状压.以后任意进制 ...

  8. Codeforces Round #297 (Div. 2) [ 折半 + 三进制状压 + map ]

    传送门 E. Anya and Cubes time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  9. hdu3001(三进制状压)

    题目大意: 现在给你一个有n个点和m条边的图,每一条边都有一个费用,每个点不能经过超过两次,求所有点至少遍历一次的最小费用 其中n<=10 m没有明确限制(肯定不会超过1e5) 一看到这个数据范 ...

随机推荐

  1. CentOS6.5安装MySQL5.7(也适合其他版本安装)

     1.查看是否已经安装过mysql或其依赖,若已装过要先将其删除,否则第4步使用yum安装时会报错: 方法一:yum list installed | grep mysql 方法二:rpm -qa | ...

  2. poj 1236 Network of Schools (强连通分量+缩点)

    题目大概: 每个学校都可以把软件复制好,交给它名单上的学校. 问题A:把软件复制成几份,然后交给不同的学校,所有学校才能够都有软件. 问题B:添加几条边,能使得这个图变成强连通图. 思路: 找出所有的 ...

  3. vue——做了一个幼稚的小页面

    我的小花花没有转起来,不开心  ̄へ ̄

  4. mac终端快捷键

    mac终端快捷键: http://www.jianshu.com/p/e6c364084c22

  5. <linux下内置命令和外部命令>

    Linux下内置命令和外部命令 1.linux的命令可以分为内部命令和外部命令: 内部命令在系统启动时就调入内存,是常驻内存的,所以执行效率高. 而外部命令是系统的软件功能,用户需要时才从硬盘中读入内 ...

  6. mysql数据库的数据变更事件获取以及相关数据

    https://medium.com/@Masutangu/udf-trigger%E5%AE%9E%E6%97%B6%E7%9B%91%E6%8E%A7mysql%E6%95%B0%E6%8D%AE ...

  7. ubuntu配置硬盘开机自动挂载

    1.创建/media/fly文件夹 sudo mkdir /home/fly    #根据个人喜好命名 2.获取要自动挂载的分区的UUID和分区类型TYPE sudo blkid 出现如下结果:   ...

  8. CF1174D Ehab and the Expected XOR Problem

    思路: 使用前缀和技巧进行问题转化:原数组的任意子串的异或值不能等于0或x,可以转化成前缀异或数组的任意两个元素的异或值不能等于0或x. 实现: #include <bits/stdc++.h& ...

  9. javascript之常用正则表达式

    一.校验数字的表达式 1 数字:^[0-9]*$ 2 n位的数字:^\d{n}$ 3 至少n位的数字:^\d{n,}$ 4 m-n位的数字:^\d{m,n}$ 5 零和非零开头的数字:^(0|[1-9 ...

  10. mathtype 章节号 Equation Chapter 1 Section 1 的去除

    mathtype 章节号 Equation Chapter 1 Section 1 的去除 转:http://hi.baidu.com/17ximm/blog/item/2882413e92fc96c ...