1273-宣传墙
内存限制:64MB 时间限制:1000ms 特判: No
题目描述:
ALPHA 小镇风景美丽,道路整齐,干净,到此旅游的游客特别多。CBA 镇长准备在一条道路南 面 4*N 的墙上做一系列的宣传。为了统一规划,CBA 镇长要求每个宣传栏只能占相邻的两个方格 位置。但这条道路被另一条道路分割成左右两段。CBA 镇长想知道,若每个位置都贴上宣传栏, 左右两段各有有多少种不同的张贴方案。 例如: N=6,M=3, K=2, 左,右边各有 5 种不同的张贴方案
输入描述:
第一行: T 表示以下有 T 组测试数据 ( 1≤T ≤8 ) 接下来有T行, 每行三个正整数 N M K 分别表示道路的长度,另一条道路的起点和宽度 (1≤ N ,M ≤ 1 000 000, 1≤ K ≤ 100000)
输出描述:
每组测试数据,输出占一行:两个整数,分别表示左右两段不同的张贴方案数。由于方案总数 可能很大,请输出对 997 取模后的结果。
样例输入:
复制
2 6 3 2 5 3 2
样例输出:
5 5 5 1
AC:代码 0ms
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef long long int lli; typedef unsigned long long llu; const int maxn = 1<<4; const int mod = 997; struct matrix{ int s[maxn][maxn]; }x; int n,m,k; int s1,s2; matrix MulMatrix(matrix a,matrix b,int c,int d,int e) { matrix res; for(int i = 0;i<c;i++){ for(int j = 0;j<d;j++){ int x = 0; for(int k = 0;k<e;k++){ x = (x + a.s[i][k] * b.s[k][j])%mod; } res.s[i][j] = x; } } return res; } matrix MatrixPow(matrix a,int b) { matrix res; memset(res.s,0,sizeof(res.s)); for(int i = 0;i<maxn;i++){ res.s[i][i] = 1; } while(b) { if(b&1) res = MulMatrix(res,a,1,maxn,maxn); b >>= 1; a = MulMatrix(a,a,maxn,maxn,maxn); } return res; } void dfs(int i,int j,int k,int u)//i 行 j 这一列的状态 k 下一列 u (ii) { if(u == 4){ x.s[i][k] ++; return; } if((j&(1<<u))){ dfs(i,j,k,u+1); return; } dfs(i,j|(1<<u),k|(1<<u),u+1); if(u+1<4 && !(j&(1<<u)) && !(j&(1<<(u+1)))){ dfs(i,j|(1<<u)|(1<<(u+1)),k,u+2); } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d %d %d",&n,&m,&k); int s1 = m-1; if(s1 == 0){ printf("0 "); } else { memset(x.s,0,sizeof(x.s)); for(int i = 0;i<maxn;i++){ dfs(i,i,0,0); } matrix y = MatrixPow(x,s1); printf("%d ",y.s[0][0]%mod); } s2 = n - s1 - k; if(s2 == 0){ printf("0\n"); } else { memset(x.s,0,sizeof(x.s)); for(int i = 0;i<maxn;i++){ dfs(i,i,0,0); } matrix y = MatrixPow(x,s2); printf("%d\n",y.s[0][0]%mod); } } return 0; }
在网上找到了一种简单一点的代码贴一下
#include <stdio.h> #include <string.h> #include <stdlib.h> const int col = 4; int row; int dp[900000][1<<4]; void dfs(int r,int c,int pre,int now) { if(c==col) { dp[r][now] += dp[r-1][pre]; dp[r][now] %= 997; return ; } if(c+1<=col) { dfs(r,c+1,pre<<1,(now<<1)|1); dfs(r,c+1,(pre<<1)|1 ,now<<1); } if(c+2<=col) { dfs(r,c+2,(pre<<2)|3,(now<<2)|3); } } int main() { int T,N,M,K; scanf("%d",&T); while(T--) { scanf("%d%d%d",&N,&M,&K); row = M - 1; if(row<=0) { printf("0 "); } else { memset(dp,0,sizeof(dp)); dp[0][(1<<col)-1] = 1; for(int i=1;i<=row;i++) { dfs(i,0,0,0); } printf("%d ",dp[row][(1<<col)-1]); } row = N - M - K + 1; if(row<=0) { printf("0\n"); } else { memset(dp,0,sizeof(dp)); dp[0][(1<<col)-1] = 1; for(int i=1;i<=row;i++) { dfs(i,0,0,0); } printf("%d\n",dp[row][(1<<col)-1]); } } return 0; }