传送门

描述:\(一堆筛子,每个筛子两个面,上面有1-6之间的数字。后一个筛子与前一个筛子的接触面的点数必须相等。\)

\(求,有多少种方案堆完筛子。(方案只关心筛子的位置,不关心是否翻转)\)

\(dp[mask][last][orientation]\),表示使用\(mask\)指示的子数组,以第\(last\)个多米诺骨牌为结尾的合法排列的方法

\(orientation\)多米诺骨牌的状态,0表示原来的方向,1表示翻转。

如果\(mask\)使用二进制表示为01010101,表示使用第0,2,4,6个多米诺骨牌排列而成,1代表使用这个位置上的数组,0代表不使用。

那么,我们先枚举所有状态,再从状态中枚举两个被用过的筛子\(last\)和\(i\)

假设last是结尾用的筛子,那么尝试接到筛子\(i\)上去

如果i和last都是原来的方向:

\(dp[mask][last][0] =sum (dp[mask][last][0],dp[premask][i][0])。\)

如果i是翻转的,last是原来的方向:

\(dp[mask][last][0] =sum (dp[mask][last][0],dp[premask][i][1])。\)

如果i是原来的方向,last是翻转的方向:

\(dp[mask][last][1] =sum (dp[mask][last][1],dp[premask][i][0])。\)

如果i和last都是翻转的方向:

\(dp[mask][last][1] =sum (dp[mask][last][1],dp[premask][i][1])。\)

最后只要将所有\(dp[1<<n-1][i][0]\)和\(dp[1<<n-1][i][1]\)累加所得即可(当\(s[i]==t[i]\)时不用加\(dp[1<<n-1][i][1]\))。

特殊情况——如果所有的多米诺骨牌都是一样的,那么所有的顺序都是有效的,即全排列。

自己仿照标称的代码

标程

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int s[20],t[20];
ll p[25];
ll dp[70000][20][2];
int main()
{ int T,i,mask,last,n;
p[0]=1;
for(i=1;i<=20;i++)p[i]=p[i-1]*i%mod;
scanf("%d",&T);
while(T--)
{
int fl=0;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d%d",&s[i],&t[i]);
for(i=1;i<n;i++)
if((s[i]==s[0]&&t[i]==t[0])||(s[i]==t[0]&&t[i]==s[0])){}
else {fl=1;break;} // 特殊情况——如果所有的多米诺骨牌都是一样的,那么所有的顺序都是有效的。
if(fl==0)
{
printf("%lld\n",p[n]);
continue;
} memset(dp,0,sizeof dp); //初始化,表示每个骨牌都有一个初始状态
for(i=0;i<n;i++)
dp[1<<i][i][0]=dp[1<<i][i][1]=1; for(mask=3;mask<(1<<n);mask++)
{
for(last=0;last<n;last++)
{
if((mask&(1<<last))==0)continue;
int premask=mask-(1<<last); for(i=0;i<n;i++)
{
if((premask&(1<<i))==0)continue; //i和last都是原来的方向
if(t[i]==s[last])
dp[mask][last][0] = (dp[mask][last][0]+dp[premask][i][0])%mod;
//i是翻转的,last是原来的方向
else if(s[i]==s[last])
dp[mask][last][0] = (dp[mask][last][0]+dp[premask][i][1])%mod;
//i是原来的方向,last是翻转的方向
if(t[i]==t[last])
dp[mask][last][1] = (dp[mask][last][1]+dp[premask][i][0])%mod;
//i和last都是翻转的方向
else if(s[i]==t[last])
dp[mask][last][1] = (dp[mask][last][1]+dp[premask][i][1])%mod;
}
}
}
//计算所有可能的情况
ll ans=0;
for(i=0;i<n;i++)
{
ans=(ans+dp[(1<<n)-1][i][0])%mod;
if(s[i]!=t[i])//特殊情况不再统计
ans=(ans+dp[(1<<n)-1][i][1])%mod;
}
printf("%lld\n",ans);
}
}

(Lineup the Dominoes筛子)三维状压的更多相关文章

  1. Long Dominoes(ZOJ 2563状压dp)

    题意:n*m方格用1*3的方格填充(不能重叠)求有多少种填充方法 分析:先想状态,但想来想去就是觉得不能覆盖所有情况,隔了一天,看看题解,原来要用三进制 0 表示横着放或竖放的最后一行,1表示竖放的中 ...

  2. codevs1358棋盘游戏(状压dp)

    1358 棋盘游戏  时间限制: 1 s  空间限制: 64000 KB  题目等级 : 大师 Master     题目描述 Description 这个游戏在一个有10*10个格子的棋盘上进行,初 ...

  3. 棋盘 || 状压DP

    题意:有一个n*m的棋盘(n,m≤80,n*m≤80)要在棋盘上放k(k≤20)个棋子,使得任意两个棋子不相邻(每个棋子最多和周围4个棋子相邻).求合法的方案总数. 思路:对于每一行,如果把没有棋子的 ...

  4. UOJ #129 / BZOJ 4197 / 洛谷 P2150 - [NOI2015]寿司晚宴 (状压dp+数论+容斥)

    题面传送门 题意: 你有一个集合 \(S={2,3,\dots,n}\) 你要选择两个集合 \(A\) 和 \(B\),满足: \(A \subseteq S\),\(B \subseteq S\), ...

  5. codeforces 342D Xenia and Dominoes(状压dp+容斥)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud D. Xenia and Dominoes Xenia likes puzzles ...

  6. HDU5731 Solid Dominoes Tilings 状压dp+状压容斥

    题意:给定n,m的矩阵,就是求稳定的骨牌完美覆盖,也就是相邻的两行或者两列都至少有一个骨牌 分析:第一步: 如果是单单求骨牌完美覆盖,请先去学基础的插头dp(其实也是基础的状压dp)骨牌覆盖 hiho ...

  7. 【HDU 4771 Stealing Harry Potter's Precious】BFS+状压

    2013杭州区域赛现场赛二水... 类似“胜利大逃亡”的搜索问题,有若干个宝藏分布在不同位置,问从起点遍历过所有k个宝藏的最短时间. 思路就是,从起点出发,搜索到最近的一个宝藏,然后以这个位置为起点, ...

  8. 状压dp入门

    状压dp的含义 在我们解决动态规划题目的时候,dp数组最重要的一维就是保存状态信息,但是有些题目它的具有dp的特性,并且状态较多,如果直接保存的可能需要三维甚至多维数组,这样在题目允许的内存下势必是开 ...

  9. 状态压缩动态规划 状压DP

    总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...

随机推荐

  1. Codeup 25593 Problem G 例题5-7 求圆周率pi的近似值

    题目描述 用如下公式 4*Π = 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 - 1/15 - 求圆周率PI的近似值,直到发现某一项的绝对值小于10-6为止(该项不 ...

  2. 最长回文子窜O(N)

    字符窜同构的性质:同构字符窜拥有最小和最大的表示方法: 最长回文子窜: 1.首先暴力法:(n三方) 枚举每个起点和终点,然后单向扫描判断是不是回文子窜: 2.中心扩散法,(N方) 枚举每个中点,向外扩 ...

  3. 1年左右的Java开发经验面试者的心得

    面试,相信只要踏入这行业的人都会经历,不同的公司有不同的面试流程,但是综合起来,其实还是大体一致的!只有不断的总结自己的面试经历,得出自己的技术不足点,才能更好的去查缺补漏,从而更加自信的进行面试找到 ...

  4. 怎么快速学python?酒店女服务员一周内学会Python,一年后成为程序员

    怎么快速学python?有人说,太难!但这个女生却在一个星期内入门Python,一个月掌握python所有的基础知识点. 说出来你应该不信,刚大学毕业的女生:琳,一边在酒店打工,一边自学python, ...

  5. 原创Pig0.16.0安装搭建

    tar -zxvf pig-0.16.0.tar.gz -C ~   vi ~/.bash_profile export PIG_HOME=/home/hadoop/pig-0.16.0 export ...

  6. 装机摸鱼日志--ubuntu16.04安装网易云音乐客户端

    之前装的网易云音乐不指定啥原因不能用了,所以打算重新装一个,但是进官网只有deepin15和ubuntu18.04版本的安装包.然后我装了一下18.04的安装包,但是没有成功.甚至因为更换glibc差 ...

  7. linux之cat 操作

    1.查看或创建 cat 1.txt #如果目录有这个文件则会打开查看,没有则会创建 2.压缩空白 cat 1.txt 我是第一行 我是第二 行 cat -bs 1.txt # 变成 cat 1.txt ...

  8. BUUOJ [BJDCTF 2nd]elementmaster

    [BJDCTF 2nd]elementmaster 进来就是这样的一个界面,然后就查看源代码 转换之后是Po.php,尝试在URL之后加上看看,出现了一个“.“ ....... 迷惑 然后看了wp 化 ...

  9. jmeter 聚合报告参数解释

    label:每个请求的名称 样本:发送给服务器的请求数量 平均值:平均响应时间,默认情况下是单个 Request 的平均响应时间,当使用了 Transaction Controller 时,也可以以T ...

  10. shiro:集成Spring(四)

    基于[加密及密码比对器(三)]项目改造 引入相关依赖环境 shiro-spring已经包含 shiro-core和shiro-web 所以这两个依赖可以删掉 <!--shiro继承spring依 ...