题意 : 有一个三角形架,两个人轮流游戏,每次都可以涂黑一条边,如果涂黑这条边之后恰好凑好了一个小三角形,就可以继续画边,给出初始局势,问在双方都足够理智的情况下,先手胜还是后手胜,或者平局

这种博弈问题,最近见了几道,总的来说是需要做到:

①选择合适的方式记录状态(即局势),且记录的时候要考虑双方的双向性,比如“A吃了三个糖果,B吃了五个糖果”与“A吃了五个糖果,B吃了三个糖果”是两个对称的,不同的局势,一般要记为两种

②可以用dp来记录不同局势下的最优解,同时能做到局面换手

③进行局面转移,可以用dfs来进行搜索,dfs做这个事情很适合,即选择搜索树的临节点

这道题的状态情况比较多,因此用状压dp来做,即18位二进制位,第i位为1,则代表第i条边涂黑了。形成的十进制数记为now

那么就用dp[now][0]记录now所代表的局势下,该先手画边的情形下的最优解,对应的,dp[now][1]是后手的最优解。

用dfs搜索局势,也是依赖于这个题目的规模很小,如果涂了某条边能画出更多的三角形,当前人可以继续画边,因此就表示为

dp[now][state]=max(dp[now][state],dfs(next,state)+add);

这里state表示当前是先手还是后手,next是画了这条边之后的局势,add是当前手画边之后多出来的三角形数目,容易写错的是dfs(next,state)中的state,不用改变

如果不能画出更多的三角形,并不代表这个状态不用遍历了,而是:

dp[now][state]=max(dp[now][state],last-dfs(next,1-state));

用1-state代表局面换手

code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#define LL long long
using namespace std;
const double pi=acos(-1);
const int Mod=1e9+7;
const double eps=1e-9;int dp[1<<22][2];//store the answer for each status
int vis[1<<22][2];//mark when a state is calculated,and notice that state is bidirectional.int calcu(int n)
{int ans=0;bool vis[20]={false};for(int i=1;i<=18;i++){if((n>>i)&1)vis[i]=true;}for(int i=0;i<6;i++){if(vis[i*3+1]&&vis[i*3+2]&&vis[i*3+3])ans++;}if(vis[3]&&vis[5]&&vis[7])ans++;if(vis[6]&&vis[11]&&vis[13])ans++;if(vis[9]&&vis[14]&&vis[16])ans++;return 9-ans;
}
int dfs(int now,int state)
{if(vis[now][state])return dp[now][state];int last=calcu(now);vis[now][state]=1;for(int i=1;i<=18;i++){if(((now>>i)&1)==0)//edge i has not be colored.{int next=now|(1<<i);int tmp=calcu(now)-calcu(next);if(tmp>0)dp[now][state]=max(dp[now][state],dfs(next,state)+tmp);elsedp[now][state]=max(dp[now][state],last-dfs(next,1-state));}}return dp[now][state];
}
int n;
int main()
{//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);int now=0;int edge=0;while(cin>>n){if(n==0)break;now=0;memset(dp,0,sizeof(dp));memset(vis,0,sizeof(vis));while(n--){cin>>edge;now|=(1<<edge);}int last=calcu(now);//cout<<now<<" "<<last<<endl;int numa,numb;numa=dfs(now,0);numb=last-numa;//cout<<numa<<" "<<numb<<endl;if(numa>numb)cout<<"Andy wins"<<endl;else if(numa<numb)cout<<"Ralph wins"<<endl;else cout<<"Draw"<<endl;}
}

Gym 100015 F Fighting for Triangles 博弈,状压dp相关推荐

  1. nowcoder 多校算法寒假训练营(第二场)F 德玛西亚万岁(状压DP,位运算)

    状态DP中很经典的一道题,除了从牛变成人之后好像就没什么变化了吧. 可以预处理出同一行内不会相邻的所有状态. 地图的每一行的01互换后,用一个数字储存. 对于每一个状态,若其与地图&运算的结果 ...

  2. 【状压DP】最优配对问题(jzoj 3420)

    最优配对问题 jzoj 3420 题目大意: 在平面上有n个点,现在要把他们拼成n/2对,拼接两个点的代价是他们的平面距离,现在问代价总和最小是多少 输入样例 4 8730 9323 -3374 39 ...

  3. Codeforces Gym 100676G Training Camp 状压dp

    http://codeforces.com/gym/100676 题目大意是告诉你要修n门课,每门课有一个权值w[i], 在第k天修该课程讲获得k*w[i]的学习点数,给出了课程与先修课程的关系,要修 ...

  4. 【Gym - 101915D】Largest Group(二分图最大团,状压dp)

    题干: 大黑山上有小小民和小小涛两种物种,山东人小李想要研究这两种物种的关系 奇怪的是大黑山上有相同数量的小小民和小小涛.小李数了数一共有 P 个,小李分别给P个小小民和小小涛编号 1 - P 号,已 ...

  5. Gym - 101853E E. Maximum Sum (状压DP)

    原题地址:https://codeforces.com/gym/101853/problem/E 题意:给出一个n*n的矩阵,矩阵中每一个格子都有一个权值,选择一个格子就能拿到当前的权值,但是同时就不 ...

  6. [九省联考2018]一双木棋chess(状压DP+博弈论+Minmax搜索)

    洛谷题目传送门 解题思路 nnn和mmm都很小,很容易想到状压DP 题目描述的规则大致是长这个样子 也就是说填的位置单调递减,我们大胆一点,设一个10进制的状压,表示每一列填到了那个位置,那么这个数要 ...

  7. POJ 1038 Bugs Integrated Inc (复杂的状压DP)

    \(POJ~1038~~*Bugs~Integrated~Inc:\) (复杂的状压DP) \(solution:\) 很纠结的一道题目,写了大半天,就想练练手,结果这手生的.其实根据之前那道炮兵阵地 ...

  8. UVA10296 Jogging Trails(中国邮递员问题)(欧拉回路、一般图最大权匹配 / 状压DP)

    整理的算法模板合集: ACM模板 目录 思路 UVA10296 Jogging Trails 题目翻译: 给你n个点,m条无向边,每条边有一定的距离数值,构造成一个连通图.问从任意一点出发,遍历所有的 ...

  9. POJ 2411 Mondriaan‘s Dream(最清楚好懂的状压DP讲解)(连通性状态压缩DP)

    poj 2411 Mondriaan's Dream(最清晰的状压DP解析) 闫氏DP大法好 我们这里是一列一列地来,因为是一个棋盘性的状态压缩DP,从哪个方向都一样 摆放的小方格总方案数 等价于 横 ...

  10. 【每日DP】day2、P1879 [USACO06NOV]Corn Fields G玉米地(状压DP模板题)难度⭐⭐⭐★

    昨天的每日DP我还在写01背包,今天就到状压DP了,真刺激. P1879 [USACO06NOV]Corn Fields G 题目链接 输入 2 3 1 1 1 0 1 0 输出 9 一道简单的状压D ...

最新文章

  1. 30天敏捷结果(4):放弃一些事情
  2. 基于Quartus II的在线调试方法
  3. 免费的400GB网络存储空间
  4. 开源学习管理系统(LMS)的比较
  5. uart ttl通讯测试可以短接吗_精讲!UART、RS232、RS422、RS485,绝了
  6. MySQL新建存储过程出现:ERROR 1558 (HY000): Column count of mysql.proc is wrong. Expected 20, found 16. Create
  7. 洛谷——P2637 第一次,第二次,成交
  8. linux下查找大文件和大目录
  9. linux shell 基础试题,linux基础shell考试试卷
  10. 阅读笔记《量产必备的毫米波雷达》
  11. 纯CSS实现点击一个元素,背景颜色切换
  12. JVM 的GC 算法 分析
  13. 《wireshark》怎么抓包
  14. 计算机格式为gpt怎么更改,硬盘格式转换,手把手教你如何将硬盘mbr格式转换为gpt格式...
  15. 第一篇——胡咧咧之动漫素材如何最有效最快的查找下载,动漫网站有哪些?
  16. 公司宣传片拍摄文案怎么写?
  17. [GXYCTF2019]BabyUpload
  18. yolov5昆虫识别模型测试
  19. ftp 之 servU 15.1的安装及配置
  20. unicode 生僻字_基于Unicode编码技术的地名生僻字库研究

热门文章

  1. ROS实践1:publisher详解
  2. 【论文写作】——设置中英文字体
  3. python实例练习(2)递归:科赫曲线的绘制
  4. 关于开通博客的一些感想
  5. xbox手柄映射_如何在Windows 10中重新映射Xbox One控制器的按钮
  6. php如何做拆弹,拆弹有多难?千万别被《拆弹专家2》给骗了,不可能遇到这种炸弹...
  7. 树莓派CM4封装AD底座使用分享
  8. 在EXCEL中插入超级链接
  9. 《剑指offer》读后感
  10. 夜神模拟器 Nox Player 雷电模拟器 掉线 连不上 运行不显示的解决方案