zoukankan      html  css  js  c++  java
  • 空间漫游(SAC大佬的测试)

    题目描述
    由于球哥和巨佬嘉诚交了很多保护费,我们有钱进行一次 d 维空间漫游。
    d 维空间中有 d 个正交坐标轴,可以用这些坐标轴来描述你在空间中的位置和移动的方
    向。例如,d = 1 时,空间是一个数轴,方向有左或右;d = 2 时,空间是一个平面,方向为
    上下左右之一;d = 3 时,空间是一个三维空间,方向为上下左右前后之一;d≥4 时同理。
    形式化地描述,d 维空间中共有 2d 个方向,分别对应平行于 d 个坐标轴的正方向和负
    方向。虽然这 2d 个方向可以线性组合出无限个方向,但这不在本题的讨论范围中。可以用
    一个 d 维向量来描述一个 d 维空间中的方向,其中一维是 1 或-1,其余维度均为 0。如,d=4
    时,几个可能的方向是(0,1,0,0)、(0,0,-1,0)等,而(1,1,0,0)不是一个本题中讨论的方向。
    你在开始漫游之前,要为自己制定一条路线。你打算一共走 2N 步,每步选择 2d 个方
    向中的一个,并沿着该方向走 1 单位长度的距离。并且,你希望漫游结束后能回到开始时的
    起点。
    请计算有多少条不同的路线满足上述要求,并输出其 mod 1,000,000,007 的值。两条路
    线被认为不同当且仅当存在一步,两条路线在该步选择的方向不同。
    输入格式
    输入仅一行,两个用空格分开的非负整数 d,N。
    输出格式
    输出仅一行,仅一个整数表示符合要求的路线条数 mod 1,000,000,007。
    样例输入 1
    2 0
    样例输出 1
    1
    样例解释 1
    长度为 0 的路线只有一条
    样例输入 2
    2 1
    样例输出 2
    4
    样例解释 2
    路线 1:(1,0), (-1,0)
    路线 2:(-1,0), (1,0)
    路线 3:(0,1), (0,-1)
    路线 4:(0,-1), (0,1)
    样例输入 3
    3 2
    样例输出 3
    90

    %%%SAC巨佬https://home.cnblogs.com/u/NaVi-Awson

    5 分算法
    对于 N = 0,显然路线只有一条,输出 1 即可,复杂度 O(1)。


    20 分算法
    结合 5 分算法,对于另外的 d = 1,我们可以用 f[i][j]表示第 i 步走到 j 这个位置的方
    案数,f[i][j] = f[i-1][j-1]+f[i-1][j+1],因为会有负值,我们可以将整个数组向右平移,即
    可求解。复杂度 O(N^2 )。


    60 分算法
    结合 20 分算法,并且由它启发,我们开三维的数组 f[i][x][y],第 i 步走到二位位置
    坐标(x,y)方案数,由四个方向转移过来,复杂度 O(N^3 )。


    100 分算法
    我们发现到后面维度 d 适合 n 一个数量级的,显然我们不可以单独地把每一个维度拿
    出来单独研究。
    我们发现既然要求走到原点,那是不是就是在每个正交轴上的投影均为 0。就等于说我
    在某一维度上向“外”走 m 步,就一定要走回来 m 步。
    我们试着定义方程 f[i][j]表示在前 i 个维度向外走了 j 步(即总共走了 2*j 步)的方案数。
    如何转移?我们正考虑当前的 i 维,我并不关心前 i-1 维是怎样走的,那是不是状态是
    由 f[i-1][j-k],0<=k<=j 转移过来的。那么我肯定不能简单的相加。

    考虑本质,f[i-1][j-k]表示从前 i-1 维向外走了 j-k 步,那么剩下的 k 步是要在这一维里面走的。

    我要把 j-k 和 k 有机融合在一起。

    我们想到了组合数。
    C(2*k,2*j) 表示我们在这总共走的 2*j 步中选取 2*k 步为当前这一维走的。
    那么对于 f[i][j-k],我们还要乘上一个 C (2*k,2*j)
    但这还是不够,我们还没考虑这 2*k 步中是怎样走的。因为我们刚才说过了 2*k 步有向
    “外”走的也有向“内”走的,那么还有乘一个 C(k,2*k) 。
    综上转移方程就是
    f[i][j]=sum{f[i-1][j-k]* C(k,2*k)*C(2*j,2*k)}

    对于组合数用阶乘逆元
    复杂度 O(d*N^2 )

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 typedef long long lol;
     7 int Mod=1000000007;
     8 lol A[10001],B[10001],f[201][201];
     9 int d,n;
    10 lol C(int x,int y)
    11 {
    12   if (x==0||y==0) return 1;
    13   lol fz=B[x];
    14   lol fm=(A[y]*A[x-y])%Mod;
    15   return (fz*fm)%Mod;
    16 }
    17 int main()
    18 {int i,j,k;
    19   cin>>d>>n;
    20   A[0]=1;
    21   A[1]=1;
    22   for (i=2;i<=2*n;i++)
    23     A[i]=((Mod-Mod/i)*A[Mod%i])%Mod;
    24   for (i=1;i<=2*n;i++)
    25     A[i]=(A[i]*A[i-1])%Mod;
    26   B[0]=1;
    27   for (i=1;i<=2*n;i++)
    28     B[i]=(B[i-1]*i)%Mod;
    29   f[0][0]=1;
    30   for (i=1;i<=d;i++)
    31     {
    32       for (j=0;j<=n;j++)
    33     {
    34       for (k=0;k<=j;k++)
    35         {
    36           f[i][j]+=(f[i-1][j-k]*C(2*j,2*k)%Mod)*C(2*k,k)%Mod;
    37           f[i][j]%=Mod;
    38         }
    39     }
    40     }
    41 cout<<f[d][n];
    42 }
  • 相关阅读:
    test
    设置section的距离
    UISearchBar的应用
    Centos6.6 系统优化
    Linux系统之间文件传输 scp 命令
    MySQL 数据库安装
    AWS中国EC2 公网IP登录免pemKEY修改shh 配置文件
    Ubuntu 16.04 Chrome浏览器安装flash player插件
    Centos6.6 yum源更新
    qume-kvm 命令管理
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7543527.html
Copyright © 2011-2022 走看看