[状压dp] hdu 4064 Carcassonne
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4064
Carcassonne
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 857 Accepted Submission(s): 326
Square tiles are printed by city segments,road segments and field segments.

The rule of the game is to put the tiles alternately. Two tiles share one edge should exactly connect to each other, that is, city segments should be linked to city segments, road to road, and field to field.

To simplify the problem, we only consider putting tiles:
Given n*m tiles. You can rotate each tile, but not flip top to bottom, and not change their order.
How many ways could you rotate them to make them follow the rules mentioned above?
Each case starts with two number N,M(0<N,M<=12)
Then N*M lines follow,each line contains M four-character clockwise.
'C' indicate City.
'R' indicate Road.
'F' indicate Field.
3
1 1
RRRR
1 2
RRRF FCCC
8 8
FCFF RRFC FRCR FRFR RCCR FFCC RRFF CRFR
FRRC FRFR CCCR FCFC CRRC CRRR FRCR FRFR
RRCR FRRR CCCR FFFC RRFF RFCR CCFF FCCC
CFCF RRFF CRFR FFRR FRRF CCRR FFFC CRRF
CFRR FFFF FFFF RRFF RRRR RCRR FFCC RFRF
RRCF FRFR FRRR FRFR RCCR RCCC CFFC RFRF
CFCF FRFF RRFF FFFF CFFF CFFF FRFF RFRR
CCRR FCFC FCCC FCCC FFCC FCCF FFCC RFRF
Case 1: 4
Case 2: 1
Case 3: 1048576
Statistic | Submit | Discuss | Note
题目意思:
每一个格子有四条边,每条边有一种颜色,求通过旋转格子,使相邻格子公共边颜色同样,总的种数。
解题思路:
状态压缩dp
格子不多仅仅有12个,对于每一行维护两种状态,上边的颜色状态up和下边的颜色状态dw,一行搜完后,用上一行的dw状态(也就是当前行的up状态)更新当前行的dw状态。
滚动数组处理。
剪枝:当一个格子四边都是一样颜色的话直接*4,不用再枚举那一条边在上面
代码:
//#include<CSpreadSheet.h> #include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; #define Maxn 15
char sa[Maxn][Maxn][5];
ll dp[2][1100000];
int ba[Maxn],n,m,cur,mul;
map<char,int>myp; void dfs(int r,int nu,int up,int dw,int ri)
{
if(nu>m)
{
if(r==1)
{
dp[cur][dw]+=mul;
dp[cur][dw]%=M;
}
else
{
dp[cur][dw]+=(dp[cur^1][up]*mul)%M;
dp[cur][dw]%=M;
}
return ;
}
int i;
for(i=1;i<4;i++)
if(sa[r][nu][i]!=sa[r][nu][0])
break;
if(i==4) //四个面都同样
{
mul*=4;
int a=myp[sa[r][nu][0]];
if(ri==-1||a==ri)
dfs(r,nu+1,up*3+a,dw*3+a,a);
mul/=4;
return ;
}
for(int i=0;i<4;i++)
{
int uu=myp[sa[r][nu][i]];
int rr=myp[sa[r][nu][(i+1)%4]];
int dd=myp[sa[r][nu][(i+2)%4]];
int L=myp[sa[r][nu][(i+3)%4]]; if(ri==-1||L==ri)
dfs(r,nu+1,up*3+uu,dw*3+dd,rr);
}
}
int main()
{
//cout<<pow(3.0,12.0); //freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t,cas=0; myp['F']=0;
myp['R']=1;
myp['C']=2; ba[0]=1;
for(int i=1;i<=12;i++)
ba[i]=ba[i-1]*3; scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%s",sa[i][j]);
memset(dp,0,sizeof(dp));
cur=0;
for(int i=1;i<=n;i++)
{
cur=cur^1;
mul=1;
dfs(i,1,0,0,-1);
for(int j=0;j<ba[m];j++)
dp[cur^1][j]=0;
}
ll ans=0;
for(int i=0;i<ba[m];i++)
{
ans+=dp[cur][i];
ans%=M;
}
printf("Case %d: %d\n",++cas,ans);
}
return 0;
}
[状压dp] hdu 4064 Carcassonne的更多相关文章
- [AC自己主动机+状压dp] hdu 2825 Wireless Password
题意: 给n.m,k ,再给出m个单词 问长度为n的字符串.至少在m个单词中含有k个的组成方案有多少种. 思路: 因为m最大是10,所以能够採取状压的思想 首先建立trie图,在每一个单词的结束节点标 ...
- HDU 1565&1569 方格取数系列(状压DP或者最大流)
方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 4539郑厂长系列故事――排兵布阵(状压DP)
HDU 4539 郑厂长系列故事――排兵布阵 基础的状压DP,首先记录先每一行可取的所哟状态(一行里互不冲突的大概160个状态), 直接套了一个4重循环居然没超时我就呵呵了 //#pragma co ...
- HDU 4284Travel(状压DP)
HDU 4284 Travel 有N个城市,M条边和H个这个人(PP)必须要去的城市,在每个城市里他都必须要“打工”,打工需要花费Di,可以挣到Ci,每条边有一个花费,现在求PP可不可以从起点1 ...
- HDU 3920Clear All of Them I(状压DP)
HDU 3920 Clear All of Them I 题目是说有2n个敌人,现在可以发n枚炮弹,每枚炮弹可以(可以且仅可以)打两个敌人,每一枚炮弹的花费等于它所行进的距离,现在要消灭所有的敌人 ...
- HDU 3001 状压DP
有道状压题用了搜索被队友骂还能不能好好训练了,, hdu 3001 经典的状压dp 大概题意..有n个城市 m个道路 成了一个有向图.n<=10: 然后这个人想去旅行.有个超人开始可以把他扔到 ...
- HDU 5765 Bonds(状压DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5765 [题目大意] 给出一张图,求每条边在所有边割集中出现的次数. [题解] 利用状压DP,计算不 ...
- HDU 6149 Valley Numer II 状压DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6149 题意:中文题目 解法:状压DP,dp[i][j]代表前i个低点,当前高点状态为j的方案数,然后枚 ...
- hdu 3247 AC自动+状压dp+bfs处理
Resource Archiver Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Ot ...
随机推荐
- 回文(manacher)
裸manacher 我竟然写跪了………… 一个地方(偶数)没写清楚…… 我OOXOXOXOXXOXO #include<cstdio> #include<cstdlib> #i ...
- Nubia Z5S 基于官方H207/4.4内核的Mokee4.4.4 RC3.2 (2014.7.31修复呼吸灯(能亮依旧不能呼吸))
特别感谢 yun3195 和 轻描淡写Yhw 帮忙測试 转帖请务必注明本链接地址: http://blog.csdn.net/syhost/article/details/36444259 此ROM ...
- Codeforces Round #275 (Div. 2) C - Diverse Permutation (构造)
题目链接:Codeforces Round #275 (Div. 2) C - Diverse Permutation 题意:一串排列1~n.求一个序列当中相邻两项差的绝对值的个数(指绝对值不同的个数 ...
- Android开发调试日志工具类[支持保存到SD卡]
直接上代码: package com.example.callstatus; import java.io.File; import java.io.FileWriter; import java.i ...
- 网站教学 提纲总结到ajax结束后面还有
Repeater - 重复器五个模板:HeaderTemplate - 在最上面,显示一次FooterTemplate - 最下面,显示一次ItemTemplate - 在中间,显示n次Alterna ...
- 祝贺自己itpub和csdn双双荣获专家博客标题
这是业界难以得到认同内的技能,记录下来.油...所有的钱,明天会更好.
- E. Mike and Foam(容斥原理)
E. Mike and Foam Mike is a bartender at Rico's bar. At Rico's, they put beer glasses in a special sh ...
- UVa 10616 - Divisible Group Sums
称号:给你n数字.免去m一个,这使得他们可分割d.问:有多少种借贷. 分析:dp,D01背包. 背包整数分区. 首先.整点d.则全部数字均在整数区间[0,d)上: 然后,确定背包容量,最大为20*10 ...
- Vijos P1881 闪烁的星星
背景 星光闪耀--深蓝色空间 听说过他们的语言 沉默 暮 他们称赞深相互 描写叙述 繁星, 漫天的繁星. 繁星排成一列, 我数一数呀, 一共同拥有N仅仅小星星呢. 星星们是听话的好孩子, 小岛在指挥它 ...
- HDU 3488Tour(流的最小费用网络流)
职务地址:hdu3488 这题跟上题基本差点儿相同啊... . 详情请戳这里. 另外我认为有要改变下代码风格了..最终知道了为什么大牛们的代码的变量名都命名的那么长..我决定还是把源点与汇点改成sou ...