ZJU 1346 Comparing Your Heroes 状态压缩DP 拓扑排序的计数
做多校的时候遇见一个求拓扑排序数量的题,就顺便来写了一下。
题意:
你有个朋友是KOF的狂热粉丝,他有一个对其中英雄的强弱比较,让你根据这些比较关系来给这些英雄排名。问一共有多少种排名方式。
思路:
用dp[S]记录当前状态的数量。 S表示拓扑排序中当前阶段已经被排序的点的集合。然后就可以枚举当前排序的点,转移的条件是这个点的所有前驱都被排序,而且这个点没被排序。然后转移就好了,最终状态就是所有点都完成排序。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <time.h> using namespace std; const int INF = <<;
const int MAXN = ; int dp[<<MAXN];
int pre[MAXN]; //记录每个点的前驱集合
char name[MAXN][MAXN]; //记录每个人物的名字
char str[][MAXN];
int n, m; void input() {
//读数据及其之间的关系。
//并且把他们存起来,给每一个名字一个编号
//处理出来每个点的前驱存在pre[]中
int u, v;
n = ;
memset(pre, , sizeof(pre));
for (int i = ; i < m; i++) {
scanf("%s%s", str[], str[]); for (u = ; u < n; u++) //找到这个字符串
if (strcmp(name[u], str[])==)
break;
if (u==n) strcpy(name[n++], str[]); //如果没找到,插入这个字符串 for (v = ; v < n; v++)
if (strcmp(name[v], str[])==)
break;
if (v==n) strcpy(name[n++], str[]); pre[v] |= (<<u); //u是v的前驱,所以,把u加进v的前驱集合
}
//for (int i = 0; i < n; i++) printf("%d ", pre[i]); puts(""); //输出前驱集合
} void solve() {
//动态规划
//枚举每个状态(已经有拓扑序的集合),然后枚举假如这个集合的点
memset(dp, , sizeof(dp));
dp[] = ; //初始状态 for (int S = ; S < (<<n); S++) if (dp[S]!=) { //剪枝
for (int i = ; i < n; i++) if (((S&pre[i])==pre[i]) && !(S&(<<i))) { //i的前驱全部在此状态中,并且i不在
dp[S|(<<i)] += dp[S];
}
} printf("%d\n", dp[(<<n)-]); //最终状态时所有点都被排序
} int main() {
#ifdef Phantom01
freopen("ZJU1346.txt", "r", stdin);
#endif //Phantom01 while (scanf("%d", &m)!=EOF) {
input();
solve();
} return ;
}
ZJU 1346
ZJU 1346 Comparing Your Heroes 状态压缩DP 拓扑排序的计数的更多相关文章
- ZOJ 2563 Long Dominoes(状态压缩DP)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1563 题目大意:在h*w的矩阵里铺满1*3的小矩阵,共有多少种方法 ...
- hoj2662 状态压缩dp
Pieces Assignment My Tags (Edit) Source : zhouguyue Time limit : 1 sec Memory limit : 64 M S ...
- POJ 3254 Corn Fields(状态压缩DP)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4739 Accepted: 2506 Descr ...
- [知识点]状态压缩DP
// 此博文为迁移而来,写于2015年7月15日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6jf.html 1.前 ...
- HDU-4529 郑厂长系列故事——N骑士问题 状态压缩DP
题意:给定一个合法的八皇后棋盘,现在给定1-10个骑士,问这些骑士不能够相互攻击的拜访方式有多少种. 分析:一开始想着搜索写,发现该题和八皇后不同,八皇后每一行只能够摆放一个棋子,因此搜索收敛的很快, ...
- DP大作战—状态压缩dp
题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...
- 状态压缩dp问题
问题:Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Ev ...
- BZOJ-1226 学校食堂Dining 状态压缩DP
1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MB Submit: 588 Solved: 360 [Submit][ ...
- Marriage Ceremonies(状态压缩dp)
Marriage Ceremonies Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu ...
随机推荐
- STL数组和com数组相互转换的做法
作者:朱金灿 来源:http://blog.csdn.net/clever101 STL的泛型数组是vetor,com的泛型数组类型是VARIANT.二者怎样能相互转化呢?就是说怎么把一个vector ...
- swift语言点评十七-Designated Initializers and Convenience Initializers
Swift defines two kinds of initializers for class types to help ensure all stored properties receive ...
- Linxu基本指令
一.Linux权限的概念 Linux下有两种用户:普通用户和超级用户(). 普通用户:在linux下做有限的事情: 超级用户:可以在linux系统下做任何事情,不受限制. 普通用户的提示符是“$”,超 ...
- VC++ 借助 Win32 API 绘图实现基本的细胞自动机演示
//本程序使用 Visual Studio 2015 生成的 Win32 窗口程序模板 开发//使用 Win32 API 绘图//实现基本的细胞自动机演示////目前已知问题://存在内存泄漏,但具体 ...
- [agc004c]and grid
别问我为什么咕了两天 题意: 给出一个$H\times W$的网格图A,仅由'.'和'#'构成,边界上没有'#'且至少有一个'#'.构造两个网格图B和C,大小均为$H\times W$,要求A中为'# ...
- kubernetes 项目
1:CI/CD Docker: Harbor Git Jenkins 2:微服务 istio
- 查看centos7启动项
[root@k8s-master ~]# chkconfig Note: This output shows SysV services only and does not include nativ ...
- Vue内置指令
v-text 类型: string用法: 更新元素的 textContent.如果要更新部分的 textContent ,需要使用 {{ Mustache }} 插值. v-html 类型: stri ...
- 配置 IntelliJ IDEA VM options
今天在使用maven build flex 项目的时候,build failure ,查看log后发现[ERROR] Java heap space. 原来是内存不够了.需要修改maven的运行时内存 ...
- redhat下搭建jdk+tomcat环境
由于redhat自带安装了jdk,我们需要现将其进行卸载 卸载系统自带的jdk版本: 查看自带的jdk: 输入命令:rpm -qa|grep gcj 可能看到如下类似的信息: libgcj-4.1.2 ...