zoukankan      html  css  js  c++  java
  • bzoj 4859 [BeiJing2017]机动训练

    题面

    https://www.lydsy.com/JudgeOnline/problem.php?id=4859

    题解

    和管道取珠类似

    首先把平方转化成两条路径经过的图案相同的方案数

    对于一条路径 方向一共有8种 分别是 左上 上 右上 左 右 左下 下 右下 (按照起点和终点的位置关系来确定)

    我们枚举两个方向 也就是枚举$8 imes 8$ 一共64种方向 注意到对于方向$(a,b)$ 我们发现有其他3种和它是等价的 分别是$(!a,!b),(b,a),(!b,!a)$ (!a 表示a的反方向) 所以实际上只要做$frac {8 imes 8} {4} =16$种

    对于一种情况 我们令$f[a][b][c][d]$表示两条路径的起点分别为$(a,b)$和$(c,d)$的方案数

    用记忆化搜索可以算出f数组

    然后因为上下左右的四个方向被算了两次 所以得减掉

    复杂度$O(16n^4)$

    Code

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4  
     5 ll read(){
     6     ll x=0,f=1;char c=getchar();
     7     while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
     8     while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
     9     return x*f;
    10 }
    11  
    12 char get(){
    13     char c=getchar();
    14     while(c!='.' && c!='*') c=getchar();
    15     return c;
    16 }
    17  
    18 const int mod=1e9+9;
    19 int n,m;
    20 char s[40][40];
    21 int f[33][33][33][33],g[3][3][3][3];
    22 int dx[3][3][5]={{{-1,-1,0,0,0},{0,0,0,0,0},{1,1,0,0,0}},{{-1,0,0,0,0},{0,0,0,0,0},{1,0,0,0,0}},{{-1,-1,0,0,0},{0,0,0,0,0},{1,1,0,0,0}}},dy[3][3][5]={{{-1,0,-1,0,0},{-1,0,0,0,0},{-1,0,-1,0,0}},{{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}},{{1,0,1,0,0},{1,0,0,0,0},{1,0,1,0,0}}};
    23  
    24 inline void pl(int &a,int b){a=a+b;if(a>mod) a-=mod;}
    25 inline void dec(int &a,int b){a=a-b;if(a<0) a+=mod;}
    26 int q,w,e,r;
    27  
    28 int dp(int a,int b,int c,int d){
    29     //cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
    30     if(s[a][b]!=s[c][d]) return 0;
    31     if(a<1 || a>n || b<1 || b>m || c<1 || c>n || d<1 || d>m) return 0;
    32     if(f[a][b][c][d]) return f[a][b][c][d];
    33     int sum=1;
    34     for(int d1=0;d1<3;d1++){
    35         if(dx[q][w][d1]==0 && dy[q][w][d1]==0) continue;
    36         int nwa=a+dx[q][w][d1],nwb=b+dy[q][w][d1];
    37         for(int d2=0;d2<3;d2++){
    38             if(dx[e][r][d2]==0 && dy[e][r][d2]==0) continue;
    39             int nwc=c+dx[e][r][d2],nwd=d+dy[e][r][d2];
    40             pl(sum,dp(nwa,nwb,nwc,nwd));
    41         }
    42     }
    43     return f[a][b][c][d]=sum;
    44 }
    45  
    46 int solve(int a,int b,int c,int d){
    47     if(g[a+1][b+1][c+1][d+1]!=0) return g[a+1][b+1][c+1][d+1];
    48     memset(f,0,sizeof(f));
    49 //  cout<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
    50     q=a+1,w=b+1,e=c+1,r=d+1;
    51     int ret=0;
    52     for(int i=1;i<=n;i++)
    53         for(int j=1;j<=m;j++)
    54             for(int x=1;x<=n;x++)
    55                 for(int y=1;y<=m;y++)
    56                     pl(ret,dp(i,j,x,y));
    57     g[a+1][b+1][c+1][d+1]=g[c+1][d+1][a+1][b+1]=g[1-a][1-b][1-c][1-d]=g[1-c][1-d][1-a][1-b]=ret;
    58     return ret;
    59 }
    60  
    61 int solve(int a,int b){
    62     int ans=0;
    63     for(int i=-1;i<=1;i++)
    64         for(int j=-1;j<=1;j++){
    65             if(i==0 && j==0) continue;
    66             if(i==0 || j==0) dec(ans,solve(a,b,i,j));
    67             else pl(ans,solve(a,b,i,j));
    68         }
    69     return ans;
    70 }
    71  
    72 int main(){
    73     #ifdef LZT
    74     freopen("in","r",stdin);
    75     freopen("out2","w",stdout);
    76     #endif
    77     n=read(),m=read();
    78     for(int i=1;i<=n;i++)
    79         scanf("%s",s[i]+1);
    80     int ans=0;
    81     for(int i=-1;i<=1;i++)
    82         for(int j=-1;j<=1;j++){
    83             if(i==0 && j==0) continue;
    84             if(i==0 || j==0) dec(ans,solve(i,j));
    85             else pl(ans,solve(i,j));
    86         }
    87     printf("%d
    ",ans);
    88     return 0;
    89 }
    View Code

    Review

    1. 注意模数为$10^9+9$ 我一开始写成了$10^9+7$调了半天

  • 相关阅读:
    C51学习笔记
    Keil C51与Keil ARM共存
    keil c51笔记
    css实现三角形
    微信小程序倒计时实现
    微信小程序公共组件的引用与控制
    mac上查找nginx安装位置
    charles抓取移动端app数据
    封装react组件——三级联动
    前端基础(http协议相关篇)
  • 原文地址:https://www.cnblogs.com/wawawa8/p/9346404.html
Copyright © 2011-2022 走看看