1009 荣耀的羁绊

news/2025/4/1 21:56:53/文章来源:https://www.cnblogs.com/archer233/p/18801385

题解:荣耀的羁绊

问题描述

小 hua 和他的朋友在玩一款 MOBA 类手游,游戏中有五个位置(对抗路、发育路、中路、打野、游走),每局开始前需要禁用英雄并选择英雄。每个英雄可以被推荐为一个或多个分路,玩家只能选择自己会玩的英雄,并且每个英雄只能走被推荐的分路。

给定以下信息:

  • $ n $ 个英雄及其推荐分路。
  • 五个玩家会玩的英雄集合。
  • $ Q $ 种不同的禁用英雄集合。

要求计算对于每种禁用英雄集合,有多少种合法的阵容选择。

合法阵容需满足以下条件:

  1. 所有玩家选择的英雄互不相同。
  2. 阵容中不存在被禁用的英雄。
  3. 每个玩家使用自己会玩的英雄。
  4. 每个英雄走被推荐的分路。
  5. 每个分路恰好有一个英雄。

解题思路

1. 状态压缩与预处理

由于 $ n \leq 15 $,我们可以用二进制位来表示英雄的选择集合。例如,若 $ n = 10 $,则集合 $ {1, 3, 5} $ 可以表示为二进制数 $ 000010101_2 $。

  • 预处理所有可能的英雄选择方案
    对于每个英雄选择方案 $ S $(即英雄集合),我们可以通过暴力搜索计算出其对应的合法阵容数量。具体步骤如下:

    1. 枚举五个玩家分别选择的英雄组合。
    2. 确保每个英雄只走被推荐的分路。
    3. 确保每个分路恰好有一个英雄。
    4. 记录该方案的合法阵容数量。
  • 优化搜索过程
    使用排列枚举和剪枝技巧减少无效枚举。例如:

    • 如果某个英雄无法满足当前分路需求,则立即剪枝。
    • 利用位运算加速判断英雄是否属于某个玩家的可用集合。
2. 查询时直接枚举

对于每种禁用英雄集合 $ B $,我们需要从所有英雄中排除被禁用的英雄,得到剩余可用英雄集合 $ A $。然后,枚举 $ A $ 的所有子集,累加这些子集对应的预处理结果。

  • 复杂度分析
    • 预处理阶段:共有 $ 2^n $ 种英雄选择方案,每次计算的复杂度为 $ O(5!) $(排列枚举),总复杂度为 $ O(2^n \cdot 5!) $。
    • 查询阶段:对于每个禁用集合 $ B $,枚举剩余英雄集合 $ A $ 的子集,复杂度为 $ O(Q \cdot 2^n) $。
3. 状态压缩 DP(进一步优化)

为了进一步优化预处理阶段,可以采用小型的状态压缩 DP。具体方法如下:

  1. 按照英雄数量分层枚举,逐步构建合法阵容。
  2. 在每一层中,记录当前已选英雄集合和分路分配情况。
  3. 利用位运算快速判断是否满足分路限制。

通过这种方法,可以显著减少无效枚举的数量,从而提高效率。


实现代码

以下是基于上述思路的实现代码:

#include <bits/stdc++.h>
using namespace std;const int mod = 1e9 + 7;
constexpr int N = 15;// 快速幂函数
long long qpow(long long a, long long b) {long long res = 1;while (b) {if (b & 1) res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}void solve() {int n, q;cin >> n >> q;// 输入五个玩家会玩的英雄集合vector<int> player_heroes(5, 0);for (int i = 0; i < 5; i++) {int cnt;cin >> cnt;while (cnt--) {int x;cin >> x;player_heroes[i] |= (1 << (x - 1));}}// 输入英雄的分路推荐矩阵vector<vector<int>> hero_routes(n, vector<int>(5, 0));for (int i = 0; i < n; i++) {for (int j = 0; j < 5; j++) {cin >> hero_routes[i][j];}}// 预处理所有英雄选择方案的合法阵容数量vector<int> dp(1 << n, 0);vector<int> p(5);iota(p.begin(), p.end(), 0);do {// 枚举当前分路分配方案vector<int> v(5, 0);for (int i = 0; i < 5; i++) {v[i] = player_heroes[p[i]];}// 搜索所有可能的英雄选择function<void(int, int)> dfs = [&](int u, int mask) {if (u == 5) {dp[mask]++;return;}for (int i = 0; i < n; i++) {if ((mask >> i) & 1) continue; // 已选过的英雄跳过if (((v[u] >> i) & 1) && hero_routes[i][p[u]]) { // 英雄可选且符合分路dfs(u + 1, mask | (1 << i));}}};dfs(0, 0);} while (next_permutation(p.begin(), p.end()));// 动态规划优化for (int j = 0; j < n; j++) {for (int i = 1; i < (1 << n); i++) {if ((i >> j) & 1) {dp[i] += dp[i ^ (1 << j)];}}}// 处理查询while (q--) {int ban_count;cin >> ban_count;int ban_mask = 0;while (ban_count--) {int x;cin >> x;ban_mask |= (1 << (x - 1));}int available_mask = ((1 << n) - 1) ^ ban_mask;cout << dp[available_mask] << '\n';}
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int T;cin >> T;while (T--) solve();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/908423.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenEuler RISC-V 上跑bitcoin(实战版)

不久前刚在OpenEuler 24.09 RISC-V上部署了 bitcoin,不过还没跑起来,这次我打算在这个环境下面运行一些应用服务,体验一下 OERV 的开发感觉。编译出来的 bitcoin 主要有几个命令,bitcoin-cli、bitcoind、bitcoin-util、bitcoin-wallet、bitcoin-tx和test_bitcoin。bitcoind…

javawebDay3-Maven框架

1.添加依赖 eg<dependencies><dependency><groupId></groupId><artifactId></artifactId></dependency></dependencies>从外部导入jar包等无需手动添加依赖 2.集成度高,eclipse和intellIDEA都能使用,在不同的操作系统也可以使…

Five Hundred Miles

一百英里 是自由,是初出茅庐的憧憬。 二百英里 是快乐,是逃离故里的喜悦。 三百英里 是忧伤,是萦绕心间的挂念。 四百英里 是思恋,是莺歌燕舞的家乡。 五百英里 是乡愁,是一去不返的凄凉。

day8华为机试题库继续

HJ3思路1:冒泡排序思路2:哈希表HJ4public String substring(int beginIndex) public String substring(int beginIndex, int endIndex)

Vue3管理系统开发个人信息,修改密码页面

把默认路由先重定向到/login,用户每次启动项目重新登录{path:/,redirect:/login},个人中心页面 子组件发送请求更新父组件内容const emit =defineEmits([updateUser])//更新缓存数据localStorage.setItem(pro1-user,JSON.stringify(data.form))emit(updateUser) 父级const upd…

php代码审计实战-开源项目Ascoos Framework 24 - Free Edition漏洞检测

一、下载 Ascoos Framework 24 - Free Edition 链接地址: https://sourceforge.net/projects/ascoos-fw/二、php静态分析代码审计 1.php静态分析代码审计工具使用我们之前介绍的静态分析php代码安全扫描工具系统分析 分析环境、过程、结果 分析环境:ubuntu 22.04.1分析过程:…

20242931 2024-2025-2 《网络攻防实践》第五周作业

20242931 2024-2025-2 《网络攻防实践》第五周作业 1. 实验内容 1.1 实验要求 (1) 防火墙配置:配置Linux操作系统平台上的iptables,要求过滤ICMP数据包,使得主机不接收Ping包;只允许特定IP地址(如局域网中的Linux攻击机192.168.200.13)访问主机的某一网络服务(如FTP、HTTP、…

【CTF笔记】HackINI 2021-sqli-0x1-bugku-SQL注入题wp

这个题的主题是sql注入,但是有一定安全措施阻挠,关键词:过滤、hash校验 首先进入页面,看到有登录框,输入一个admin测试密码,提示密码错误,输入其他账号root登,都是没有此用户,判断目标就是要get到admin的登录 查看到有提示,访问pls_help可以查看源代码 这个代码有几…

Pychaim集成本地部署的ollama+qwen-coder32b

服务器配置为:2个11264MiB NvidiaGPU + 16核 3.8GHz CPU + 72G 内存;部署Ollama平台,使用Qwen-coder2.5:32B模型。 1. 下载、安装并运行ollama; ollama的安装网上介绍的比较多,此处不再多讲,可以参考 Ollama全面指南:安装、使用与高级定制 若在服务器上部署ollama,确保…

[Vue] Vue 模板编译原理解析 part3

生成 JavaScript AST 我们要对整个模板的 AST 进行转换,转换为 JS AST。 我们目前的代码已经有了遍历模板 AST,并且针对不同的节点,做不同操作的能力。 我们首先需要知道 JS AST 长什么样子: function render(){return null; }上面的代码,所对应的 JS AST 如下图所示:这里…

[Vue] Vue模板编译原理解析 part3

生成 JavaScript AST 我们要对整个模板的 AST 进行转换,转换为 JS AST。 我们目前的代码已经有了遍历模板 AST,并且针对不同的节点,做不同操作的能力。 我们首先需要知道 JS AST 长什么样子: function render(){return null; }上面的代码,所对应的 JS AST 如下图所示:这里…