[状压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 ...
 
随机推荐
- 1038. Recover the Smallest Number (30) - 字符串排序
			
题目例如以下: Given a collection of number segments, you are supposed to recover the smallest number from ...
 - ANDROID 中设计模式的採用--创建型模式
			
 所谓模式就是在某一情景下解决某个问题的固定解决方式. 全部的创建型模式都是用作对象的创建或实例化的解决方式. 1 简单工厂模式 创建对象的最简单方法是使用new来创建一个对象,假设仅仅创建一种固 ...
 - URAL 1056(树形DP)
			
1056. Computer Net Time limit: 2.0 second Memory limit: 64 MB Background Computer net is created by ...
 - 《转》VC++多线程编程
			
原地址:http://www.cnblogs.com/wxfasdic/archive/2010/09/23/1833522.html 留个纪念,不错的总结.十个例子清晰列举啦多线程编程的奥妙. V ...
 - vdsm的SSL证书验证过程
			
1. Copy the VDSM certificate of the RHEV-H(Red Hat Enterprise Virtualization Hypervisor ) host to th ...
 - Dan计划:重新定义人生的10000个小时 - 阮一峰的网络日志
			
Dan计划:重新定义人生的10000个小时 - 阮一峰的网络日志 Dan计划:重新定义人生的10000个小时
 - Android-1-电话拨号程序
			
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjY1MTM4OQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
 - swift 简单语句 控制流语句
			
在 Swift 中.有两种类型的语句:简单语句和控制流语句.简单语句是最常见的.用于构造表达式和声明.控制流语句则用于控制程序运行的流程,Swift 中有三种类型的控制流语句:循环语句.分支语句和控制 ...
 - Codeforces 61E Enemy is weak 乞讨i<j<k && a[i]>a[j]>a[k] 对数的 树阵
			
主题链接:点击打开链接 意大利正在寻求称号 i<j<k && a[i]>a[j]>a[k] 的对数 假设仅仅有2元组那就是求逆序数的做法 三元组的话就用一个树状 ...
 - jquery关于表格隐藏和显示问题
			
1. 关于指定表格指定列隐藏显示 $(":checkbox[name*=month]").each(function(){ if(!$(this).attr("check ...