zoukankan      html  css  js  c++  java
  • hihoCoder #1162 : 骨牌覆盖问题·三

    #1162 : 骨牌覆盖问题·三

    Time Limit:10000ms
    Case Time Limit:1000ms
    Memory Limit:256MB

    描述

    前两周里,我们讲解了2xN,3xN骨牌覆盖的问题,并且引入了两种不同的递推方法。
    这一次我们再加强一次题目,对于给定的K和N,我们需要去求KxN棋盘的覆盖方案数。

    提示:KxN骨牌覆盖

    输入

    第1行:2个整数N。表示棋盘宽度为k,长度为N。2≤K≤7,1≤N≤100,000,000

    输出

    第1行:1个整数,表示覆盖方案数 MOD 12357

    Sample Input
    2 62247088
    Sample Output
    1399

    解题:dfs造转移方程+dp计数+快速幂优化dp
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const LL mod = 12357;
     5 int n,m;
     6 struct Matrix{
     7     int m[1<<7][1<<7];
     8     Matrix(){
     9         init();
    10     }
    11     void init(){
    12         memset(m,0,sizeof m);
    13     }
    14     Matrix operator*(const Matrix &rhs){
    15         Matrix ret;
    16         for(int k = 0; k < (1<<n); ++k)
    17             for(int i = 0; i < (1<<n); ++i)
    18                 for(int j = 0; j < (1<<n); ++j)
    19                     ret.m[i][j] = (ret.m[i][j] + m[i][k]*rhs.m[k][j])%mod;
    20         return ret;
    21     }
    22     void print(){
    23         for(int i = 0; i < 8; ++i){
    24             for(int j = 0; j < 8; ++j)
    25                 printf("%d ",m[i][j]);
    26             cout<<endl;
    27         }
    28     }
    29 };
    30 Matrix a,b;
    31 void quickPow(LL index){
    32     while(index){
    33         if(index&1) a = a*b;
    34         index >>= 1;
    35         b = b*b;
    36     }
    37 }
    38 bool tab[10][10];
    39 void dfs(int cur,int st){
    40     if(cur >= n){
    41         int ss = 0;
    42         for(int i = n-1; i >= 0; --i){
    43             ss <<= 1;
    44             ss |= tab[i][1];
    45         }
    46         b.m[st][ss]++;
    47         return;
    48     }
    49     if(!tab[cur][0]){
    50         if(!tab[cur][1]){
    51             tab[cur][0] = tab[cur][1] = true;
    52             dfs(cur+1,st);
    53             tab[cur][0] = tab[cur][1] = false;
    54         }
    55         if(cur + 1 < n){
    56             if(!tab[cur+1][0]){
    57                 tab[cur+1][0] = tab[cur][0] = true;
    58                 dfs(cur+2,st);
    59                 tab[cur+1][0] = tab[cur][0] = false;
    60             }
    61         }
    62     }else dfs(cur + 1,st);
    63 }
    64 void init(int st){
    65     memset(tab,false,sizeof tab);
    66     for(int i = 0,xst = st; i < n; ++i,xst >>= 1)
    67         tab[i][0] = xst&1;
    68     dfs(0,st);
    69 }
    70 int main(){
    71     while(~scanf("%d%d",&n,&m)){
    72         b.init();
    73         a.init();
    74         for(int i = 0; i < (1<<n); ++i) init(i);
    75         a.m[0][0] = 1;
    76         quickPow(m);
    77         printf("%d
    ",a.m[0][0]);
    78     }
    79     return 0;
    80 }
    View Code
  • 相关阅读:
    使用C#调用C++类库
    C# IntPtr类型
    C# 调用C++ dll string类型返回
    C# try、catch、finally语句
    C语言 char *、char []、const char *、string的区别与相互转换
    C# 字符串string与char数组互转!
    C#如何调用C++(进阶篇)
    Springboot通过过滤器实现对请求头的修改
    【spring事务】
    命令行参数库:McMaster.Extensions.CommandLineUtils【转】
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4862296.html
Copyright © 2011-2022 走看看