CodeForces 456D Elections(字典树+dp)
2016-09-04 15:39
344 查看
题意:给n个字符串。进行k次游戏。每局开始,字符串为空串,然后两人轮流在末尾追加字符,保证新的字符串为集合中某字符串的前缀,不能操作者输,新一轮由上一句输的人先手。
思路:在网上看的题解大多都是这种想法,刚开始看了好长时间,其实理解起来还是挺简单的,将全部的字符串插入以后,dfs将树跑一遍,从深度较深的节点得到是必败点必败点,可控点,不可控点,向上回溯。最后回溯到头结点是就得到了先手的状态。
00 代表不能控制 01代表败,10代表胜,11代表能输能赢。
这里用二进制的位运算来表示状态的转移,说实话构造的挺巧妙的,不理解的可以手动模拟一下,应该就理解了。不过感觉这种模型还是挺难想到的。
题目链接:
直接上代码吧:
思路:在网上看的题解大多都是这种想法,刚开始看了好长时间,其实理解起来还是挺简单的,将全部的字符串插入以后,dfs将树跑一遍,从深度较深的节点得到是必败点必败点,可控点,不可控点,向上回溯。最后回溯到头结点是就得到了先手的状态。
00 代表不能控制 01代表败,10代表胜,11代表能输能赢。
这里用二进制的位运算来表示状态的转移,说实话构造的挺巧妙的,不理解的可以手动模拟一下,应该就理解了。不过感觉这种模型还是挺难想到的。
题目链接:
直接上代码吧:
#include <iostream> #include <stdio.h> #include <cmath> #include <cstring> #include <algorithm> #include <map> using namespace std; #define ll long long const int maxn = 1e5+10; int n,k,top,root,q[maxn][30]; char s[maxn]; void Insert(){ int len = strlen(s); int now = root; for(int i = 0;i < len;i++){ int tmp = s[i] - 'a' + 0; if(!q[now][tmp]) q[now][tmp] = ++top; now = q[now][tmp]; } } int dfs(int now) { int flag=1,ans=0; for(int i=0;i<26;i++) { if(q[now][i]) { flag=0; ans|=dfs(q[now][i])^3;///神奇的状态转移方程 } } if(flag) ans=1; return ans; } int main() { scanf("%d%d",&n,&k); for(int i=0;i<n;i++) { scanf("%s",s); Insert(); } int ans=dfs(root); if(ans==1) printf("Second\n"); else if(ans==3) printf("First\n"); else if(ans==2&&k&1) printf("First\n"); else printf("Second\n"); return 0; }
相关文章推荐
- 字典树的基本知识及使用C语言的相关实现
- Trie树_字典树(字符串排序)简介及实现
- 详解Android应用中屏幕尺寸的获取及dp和px值的转换
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- Python实现简单字典树的方法
- LFC1.0.0 版本发布
- Android dpi,dip,dp的概念以及屏幕适配
- Python实现简单字典树的方法
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- 关于UI切图与开发 px和dp
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp