您的位置:首页 > 编程语言 > Go语言

ZOJ 2673 Hexagon and Rhombic Dominoes (状态压缩+dp)

2013-09-10 20:13 330 查看
题意:由6n^2个小三角形组成的正六边形,问你用两个小三角菱形去填满有多少种方法

解题思路:状态压缩+dp(因为只有一部分小三角形对下一层有影响)。。分上下讨论(不同的规则),情况比较多!

解题代码:

#include<cstdio>
#include<cstring>
#include<map>
#include<vector>
#include<cmath>
#include<cstdlib>
#include<stack>
#include<queue>
#include <iomanip>
#include<iostream>
#include<algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")

using namespace std ;

long long pos[100];
long long num[30];
long long dp[20][40000];
long long row , zt , limits[30] ,n;
long long su[30];
void dfs(long long  pop,long long status)
{
if(pop == su[row+1] )
{
dp[row+1][status] +=  dp[row][zt];
return ;
}

if(row+1 <= n){

if(pop % 2 == 0 ){
if(pop + 1 < su[row+1] && num[pop] == 0 )
{
dfs(pop+2,status);
dfs(pop+1,status+pos[pop/2]);
}
else
dfs(pop+1,status+pos[pop/2]);
}
else {
if(num[pop-1])
dfs(pop+1,status);
else {
dfs(pop+2,status);
}
}

}
else {
if(pop % 2 == 1 ){
if(row == n?num[pop+1] == 0: num[pop+2] ==  0)
{
if(pop + 2 == su[row+1])
dfs(pop+2,status);
else{
dfs(pop+2,status);
dfs(pop+1,status + pos[pop/2]);
}
}
else
dfs(pop+1,status+pos[pop/2]);
}
else {
if(row == n ? num[pop]:num[pop+1])
dfs(pop+1,status);
else {
if(pop + 1 < su[row+1])
dfs(pop+2,status);
}

}

}

}
void change(long long k)
{
memset(num,0,sizeof(num));
long long m = k ;
long long t = -2 ;
while(m)
{
t = t+2;
num[t] = m%2;
m = m/2;
}

}
void change1(long long k)
{
memset(num,0,sizeof(num));
long long m = k ;
long long t = -1 ;
while(m)
{
t = t+2;
num[t] = m%2;
m = m/2;
}
}
int main()
{
pos[0] = 1;
for(long long i = 1;i <= 18; i ++ )
{
pos[i] = 2* pos[i-1];
}

memset(limits,0,sizeof(limits));
int t  = 0;
while(scanf("%lld",&n)!=EOF)
{
t ++;
for(long long i = 1;i <= n;i ++)
limits[i] = n+i;
for(long long i = n+1 ;i <= 2*n ;i ++)
limits[i] =  limits[2*n -i+1] -1;
for(long long i = 1;i <= n;i ++)
su[i] = 2*(n+i) - 1;
for(long long i = n+1; i <= 2*n ;i ++)
su[i] =  su[2*n-i+1];

memset(dp,0,sizeof(dp));
dp[0][0] = 1;
for(row = 0 ; row < 2*n ; row ++)
for(zt = 0 ; zt < pos[limits[row]+1]; zt ++)
{
if(dp[row][zt])
{
if(row <= n)
change(zt);
else
change1(zt);
dfs(0,0);
}
}
if(t!= 1 )
printf("\n");

printf("%lld\n",dp[2*n][0]);
}
return 0 ;

}


View Code
ps:AC这道题 这是今天最爽的时候
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: