/*
题目的要求是用1-6六种颜色排成一列
而且必须对称。相邻不同色。不出现123456
n为偶数的时候必然无解,
因为最中心两个无法满足相邻不同色的要求
对于n奇数的情况因为是对称考虑前n/2+1的部分
这部分必然满足相邻不同色,不出现123456
同时不出现654321(翻转到另一侧不合法)
求排列的数量
题解:构造DP来解
D[i][s] 表示长度为i时以s结尾的方案数
显然ans=sum(D[n][s])(s=1,2,3,4,5,6);
构造状态 1,2,3,4,5,6
因为s=1和6由D[i][]转换过来时候要减去以s=65432和s=12345的状态
所以构造状态65432,12345
要得到65432必须从状态6543,以此类推构造654,65
同理1234,123,12;
所以一共14个状态,根据关系写出转移关系,构造矩阵加速求解
*/
#include <iostream>
#include <cmath>
#include <cstdlib>
#include<cstdio>
#include<algorithm>
#include<cstdio>
#include<ctime>
#include<cstring>
using namespace std;
const int SZ=14;
const int MOD=112233;
long long m[14][14]={
{0, 1, 1, 1, 1, 1, 0, 0, 0, 0,-1, 0, 0, 0},
{1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 0,-1, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
},init[14][14];
void multiply(long long m1[][14],long long m2[][14])
{
long long ret[SZ][SZ];
for(int i = 0; i < SZ; ++i)
{
for(int j = 0; j < SZ; ++j)
{
ret[i][j] = 0;
for(int k = 0; k < SZ; ++k)
ret[i][j] = (ret[i][j] + ((long long)m1[i][k] * m2[k][j])% MOD) % MOD;
}
}
for(int i = 0; i < SZ; ++i)
{
for(int j = 0; j < SZ; ++j)
{
m1[i][j]=ret[i][j]%MOD;
}
}
}
void solve(int n)
{
long long k[14][14],g[14][14];
for(int i=0;i<14;i++)
{
for(int j=0;j<14;j++)
{
init[i][j]=(i==j?1:0);
k[i][j]=m[i][j];
}
}
while(n)
{
if(n&1)multiply(init,k);
multiply(k,k);
n/=2;
}
for(int i=0;i<14;i++)
for(int j=0;j<14;j++)
{
if(i<6&&j==0)g[i][j]=1;
else g[i][j]=0;
}
multiply(init,g);
long long ans=0;
for(int i = 0; i < 6; ++i)
{
ans=(ans+init[i][0]%MOD)%MOD;
}
cout<<(ans+MOD)%MOD<<endl;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if((n&1)==0){puts("0");continue;}
solve(n/2);
}
return 0;
}
HDU 3893 Drawing Pictures
最新推荐文章于 2013-08-20 19:52:18 发布