题意

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. CSS之flex兼容

    我觉得写的很好的文章,但是我又没有时间去整理的. https://blog.csdn.net/u010130282/article/details/52627661 百分比 是在宽度自适应的时候要用 ...

  2. 【ACM】孪生素数问题

    孪生素数问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 写一个程序,找出给出素数范围内的所有孪生素数的组数.一般来说,孪生素数就是指两个素数距离为2,近的不能再 ...

  3. 024 Swap Nodes in Pairs 交换相邻结点

    给定一个链表,对每两个相邻的结点作交换并返回头节点.例如:给定 1->2->3->4,你应该返回 2->1->4->3.你的算法应该只使用额外的常数空间.不要修改列 ...

  4. PullToRefreshListView

    @Override protected void onRefreshing(final boolean doScroll) { /** * If we're not showing the Refre ...

  5. Maven的学习资料收集--(九) 构建SSH项目以及专栏maven

    在这里整合一下,使用Maven构建一个SSH项目 1.新建一个Web项目 可以参照前面的博客 2.添加依赖,修改pom.xml <project xmlns="http://maven ...

  6. 服务器端控件的"客户端"

    控件的服务端ID和客户端ID 比如一个ID为TextBox1的服务器端控件,在客户端访问该控件的DOM元素时 错误: var txtbox=document.getElementByID(" ...

  7. Webpack webpack+gulp实现自动构建部署

    http://www.cnblogs.com/sloong/p/5826859.html

  8. Android入门:Service入门介绍

    一.Service介绍 Service类似于Windows中的服务,没有界面,只是在后台运行:而服务不能自己运行,而是需要调用Context.startService(Intent intent);或 ...

  9. keil 系列问题

      1.为了让keil支持stm32f0系列,安装了keil4更高级的版本,但是发现编译时弹出异常提示框,经过一番折腾后找到解决办法,首先把电脑登陆账户名改为非中文的,然后卸载了keil重装就可以了. ...

  10. SpringBoot的优缺点

    优点: 1.快速构建项目 2.对主流开发框架的无配置继承 3.项目可独立运行,无须外部依赖Servlet容器 4.提高运行时的应用监控 5.极大地提高了开发.部署效率 6.与云计算的天然集成 缺点: ...