【Gym - 100837 F】Controlled Tournament【竞赛树 状态压缩】
题意:
一共NNN个人,给出任意两个人之间的胜负关系,你的编号是MMM。现在需要安排一棵竞赛树使得MMM能够胜出,问使竞赛树高度最小且MMM获胜的安排方案一共有多少个。(1≤N≤16)(1\leq N\leq 16)(1≤N≤16)
思路:
根据题意以及数据范围,可以很明显的发现这是一个状压dpdpdp,因此我们来考虑dpdpdp的状态。
既然是状态,那肯定要记录当前的状态,即选了哪些人,然后还要记录当前的胜利者,以及当前树的高度,因此dp[i][j][k]dp[i][j][k]dp[i][j][k]表示iii状态下,胜出者为jjj,树高度为kkk的安排方案数。
然后采用记忆化搜索,求取dp[i][j][k]dp[i][j][k]dp[i][j][k]时将iii分为两个子状态xxx、yyy,然后递归求取dp[x][j][k−1]dp[x][j][k-1]dp[x][j][k−1],枚举mmm为yyy状态下的胜利者并且会输给jjj,求取dp[y][m][k]dp[y][m][k]dp[y][m][k]。具体细节见代码。
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define LOG1(x1,x2) cout << x1 << ": " << x2 << endl;
#define LOG2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;
#define LOG3(x1,x2,y1,y2,z1,z2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << " , " << z1 << ": " << z2 << endl;
typedef long long ll;
typedef double db;
const int N = 1e5+100;
const int M = 1e5+100;
const db EPS = 1e-9;
using namespace std;template<class T> int getbit(T s, int i) { return (s >> i) & 1; }
template<class T> T onbit(T s, int i) { return s | (T(1) << i); }
template<class T> T offbit(T s, int i) { return s & (~(T(1) << i)); }
template<class T> int cntbit(T s) { return __builtin_popcount(s);}int c[20][20],n,win,h[20];
ll dp[1<<16][17][7];ll solve(int stat,int m,int height){if(dp[stat][m][height] != -1) return dp[stat][m][height];if(cntbit(stat) == 1){if(getbit(stat,m-1)) return dp[stat][m][height] = 1ll;else return dp[stat][m][height] = 0;}for(int i = (stat-1)&stat; i >= 1; i = (i-1)&(stat)){ //枚举子集int x = i, y = stat-i;if(!getbit(x,m-1) || h[cntbit(x)] > height-1 || h[cntbit(y)] > height-1) continue;// if(height-1 > cntbit(x) || height-1 > cntbit(y)) continue;ll ans1 = solve(x,m,height-1);ll ans2 = 0;rep(j,1,n)if(getbit(y,j-1) && c[m][j] == 1) ans2 += solve(y,j,height-1);if(dp[stat][m][height] == -1) dp[stat][m][height] = ans1*ans2; else dp[stat][m][height] += ans1*ans2;}return max(0ll,dp[stat][m][height]);
}int main()
{freopen("f.in","r",stdin);freopen("f.out","w",stdout);scanf("%d%d",&n,&win);rep(i,1,n)rep(j,1,n) scanf("%d",&c[i][j]);rep(i,1,16) h[i] = (log(i-0.5)/log(2))+2;memset(dp,-1,sizeof dp);printf("%lld\n",max(0ll,solve((1<<n)-1,win,h[n])));return 0;
}
【Gym - 100837 F】Controlled Tournament【竞赛树 状态压缩】相关推荐
- SDUT3930 - 皮卡丘的梦想2(线段树状态压缩)
皮卡丘的梦想2 Description 一天,一只住在 501 实验室的皮卡丘决定发奋学习,成为像 LeiQ 一样的巨巨,于是他向镇上的贤者金桔请教如何才能进化成一只雷丘. 金桔告诉他需要进化石才能进 ...
- 【SGU 448】Controlled Tournament(状态压缩动态规划)
题目链接 [SGU 448]Controlled Tournament 题目大意 给定比赛人员个数nnn,你希望赢的人的编号m" role="presentation" ...
- C++数据结构与算法 竞赛树, 二叉搜索树
竞赛树: tournament tree, 也是以可完全二叉树,所以使用数组描述效率最好,竞赛树的基本操作是替换最大(小)元素 赢者树和输者树: 为了便于实现,需要将赢者树限制为完全二叉树.n个参与者 ...
- 《数据结构、算法与应用 —— C++语言描述》学习笔记 — 竞赛树
<数据结构.算法与应用 -- C++语言描述>学习笔记 - 竞赛树 一.赢者树 二.二叉树的数组描述(补充) 1.声明 2.实现 三.赢者树 1.抽象数据类型 2.赢者树的表示 3.声明 ...
- 《算法竞赛进阶指南》打卡-基本算法-AcWing 93. 递归实现组合型枚举:递归与递推、dfs、状态压缩
文章目录 题目解答 题目链接 题目解答 分析: 此题和笔者另一篇博文很像,只不过是限定了个数.<算法竞赛进阶指南>打卡-基本算法-AcWing 92. 递归实现指数型枚举:递推与递归.二进 ...
- 《算法竞赛进阶指南》打卡-基本算法-AcWing 91. 最短Hamilton路径:位运算、状态压缩dp、dp
文章目录 题目解答 题目链接 题目解答 分析: 状态压缩dp是用二进制数来表示状态. 数据范围n = 20, 那么状态总量就是2202^{20}220个状态. 可以按照以下思路去思考: 哪些点被用过 ...
- CodeForces - 620E New Year Tree(线段树+dfs序+状态压缩)
题目链接:点击查看 题目大意:给出一棵无向树,每个节点都有一种颜色,接下来时m次操作: 1 x y:将x及其子树染成y的颜色 2 x:查询x及其子树上共有多少种不同的颜色 题目分析:看完这个题的第一反 ...
- POJ 2777 Count Color (线段树区间修改 + 状态压缩)
题目链接:POJ 2777 Count Color [题目大意] 给你 n 块板子, 编号1--n , 板子的颜色最多30种, 初始时 板子的颜色都是 1: 有两种操作 1 .把给定区间的板子染成一 ...
- LeetCode第 57 场力扣夜喵双周赛(差分数组、单调栈) and 第 251 场力扣周赛(状态压缩动规,树的序列化,树哈希,字典树)
LeetCode第 57 场力扣夜喵双周赛 离knight勋章越来越近,不过水平没有丝毫涨进 1941. 检查是否所有字符出现次数相同 题目描述 给你一个字符串 s ,如果 s 是一个 好 字符串,请 ...
- 设森林F对应的二叉树为B,它有m个结点,B的根p,p右子树结点个数n,森林F中第一棵树的结点个数
题目:设森林F对应的二叉树为B,它有m个结点,B的根p,p右子树结点个数n,森林F中第一棵树的结点个数 设森林F对应的二叉树为B :它的意思就是将森林F转换为二叉树. 它有m个结点 :这颗二叉树总共有 ...
最新文章
- Android 异常: failed to connect to localhost/127.0.0.1
- 史上最通俗易懂的IPFS入门介绍:01
- 18年总结及19年展望
- 4月27日微软云训练营活动-现场图集
- 在 Visual C++ 中使用内联汇编
- docker 安装kafka(快速)
- 中文NER的正确打开方式: 词汇增强方法总结 (从Lattice LSTM到FLAT)
- java安装没有jdk文件_java文件在没有安装jdk的windows下运行。
- 安信可nbiot模块_安信可wifi模组特征
- 浅谈图像识别技术原理与价值
- 给重回正路的大二学生:戒急戒躁中前行
- word中全部数字、大小写字母、标点更改为新罗马字体Times News Romans
- 视音频编解码技术零基础学习方法
- 爬虫中使用selenium实现对斗鱼直播的各个房间标题、主播id,直播内容类型和热度信息的爬取
- aspnet+sqlserver同学录校友录网站系统
- 如何下载并安装VMware虚拟机。
- 一个与众不同的苹果--苹果产品制胜之道
- 最新体感:超级街霸4
- STM32F103详细频率测量过程
- 3C产品认证免收费用项目
热门文章
- 我对Backbone的认识
- 基于OpenCV库的Gabor滤波器的实现
- 保护数据库安全十七招
- 【前端】相信你会用到的一篇笔记---CSS篇(1)
- 安卓项目连接后台服务器,android云后端服务器
- java提取日志sql,通过Java程序抽取日志中的sql语句
- php try catch 作用域,浅谈PHP中try{}catch{}的使用方法
- 怎么重装python_如何部署Jupyter Notebook用于交互式Python开发?
- go语言环境搭建及vim高亮设置
- nyoj1110 一个简单数学题