传送门

描述:\(一堆筛子,每个筛子两个面,上面有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. shell-function 删除目录和文件

    function sDelDirFile() { if [ "$#" -eq 1 ];then if [ -e "$1" ];then rm "$1& ...

  2. 智能指针 shared_ptr

    1.不支持数组 2.c++11支持make_shared,分配一次内存,构造函数为private和proteced时不能调用. 3.new初始化分配两次内存,一.分配数据块内存,二.分配控制块内存

  3. 讲讲HashMap的理解,以及HashMap在1.7和1.8版本的变化(2020/4/16)

    HashMap的适用场景,作用,优缺点

  4. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十二)之Error Handling with Exceptions

    The ideal time to catch an error is at compile time, before you even try to run the program. However ...

  5. D. AB-string

    https://codeforces.com/contest/1238/problem/D 题目大意:统计good string的个数,good string的定义,给定的字符串中含有回文段落, 题解 ...

  6. vue2.x学习笔记(十五)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12609450.html. 组件的自定义事件 这里来学习一下组件中的自定义事件. 事件名 不同于组件名和prop,事 ...

  7. [linux][nginx] 通过nginx扩展nginx-rtmp-module简单做了一个流媒体直播

    做的过程出现很多问题,环境其实就需要nginx就可以,然后就是在播放的问题,m3u8的格式,mac直接访问就支持,苹果系统原生H5支持m3u8,还有就是手机直接访问也支持!但是其他其他系统PC端不支持 ...

  8. 【mybatis xml】数据层框架应用--Mybatis 基于XML映射文件实现数据的CRUD

    使用MyBatis框架进行持久层开发 MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架. MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索. MyBa ...

  9. react: typescript system params method optimize

    import * as _ from "lodash"; import paramCache from "../common/param-cache" impo ...

  10. RT-Thread—STM32—在线升级(Ymodem_OTA、HTTP_OTA)

    概述 本教程主要根据官方推荐的教程进行改编,详细信息请参考OTA Downloader软件包STM32 通用 Bootloader 本例程通过自己实际搭建环境,测试总结. bootloader的制作 ...