zoukankan      html  css  js  c++  java
  • BZOJ4563[Haoi2016]放棋子

    题目描述 Description
    给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在
    这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足每行只有一枚棋子,每列只有一枚棋的限制,求有多少种方案。
    输入描述 Input Description

    第一行一个N,接下来一个N*N的矩阵。N<=200,0表示没有障碍,1表示有障碍,输入格式参考样例

    输出描述 Output Description
    一个整数,即合法的方案数。
    样例输入 Sample Input
    2
    0 1
    1 0
    样例输出 Sample Output
    1
    数据范围及提示 Data Size & Hint
     

    仔细读完题发现输入的那个矩阵一点用也没有,因为可以通过平移变成障碍全在对角线上的图。继续来思考这个问题,问题转化为将1~n这N个数排列,要求第i个数不能排列在第i个位置上,这被称之为错排问题。考虑怎么递推。设f(i)表示i个数的错拍方案数,我们要将第i个数插入之前i-1个数,(因为第i个数不能插在i位置上),假如i将插在j位置上,j有两种选择,一种是j填到i的位置上,于是问题就转化为了f(i-2);另一种j填到另外i-2的位置中,我们设新填的位置为k(k!=i && k!=j),现在我们就需要把k这个数再放在i-1个数中了,即f(i-1),由于j有i-1种情况,所以我们最后再乘一个(i-1),所以递推公式就变成了f(i)=(f(i-1)+f(i-2))*(i-1),推到这一步,我们再写一个高精度支持高加高,高乘低即可。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> PII;
    #define mem(a,b) memset(a,b,sizeof(a))
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    const int maxn=1010;
    struct data
    {
        int l,v[maxn];
        data(){l=1;mem(v,0);}
        data operator = (const int& s)
        {
            v[1]=s;
            while(v[l]>9)v[l+1]=v[l]/10,v[l]%=10,l++;
            return *this;
        }
        data operator = (const data& s)
        {
            l=s.l;
            for(int i=1;i<=l;i++)v[i]=s.v[i];
            return *this;
        }
        data operator + (const data& s)const
        {
            data c;c.l=max(l,s.l)+1;
            for(int i=1;i<=c.l;i++)c.v[i]=v[i]+s.v[i];
            for(int i=1;i<c.l;i++)if(c.v[i]>9)c.v[i+1]+=c.v[i]/10,c.v[i]%=10;
            while(c.v[c.l]>9)c.v[c.l+1]=c.v[c.l]/10,c.v[c.l]%=10,c.l++;
            while(!c.v[c.l])c.l--;
            return c;
        }
        data operator * (const int& s)const
        {
             data c;c.l=l;
             for(int i=1;i<=c.l;i++)c.v[i]=v[i]*s;
             for(int i=1;i<c.l;i++)if(c.v[i]>9)c.v[i+1]+=c.v[i]/10,c.v[i]%=10;
             while(c.v[c.l]>9)c.v[c.l+1]=c.v[c.l]/10,c.v[c.l]%=10,c.l++;
             while(!c.v[c.l])c.l--;
             return c;
        }
    }f[210];
    void print(data a){for(int i=a.l;i;i--)printf("%d",a.v[i]);}
    int n;
    int main()
    {
        n=read();
        f[1]=0;f[2]=1;
        for(int i=3;i<=n;i++)f[i]=(f[i-1]+f[i-2])*(i-1);
        print(f[n]);
        return 0;
    }
    View Code
  • 相关阅读:
    pandas.DataFrame.to_excel
    python list [:1]
    python 读取文件
    pandas 中的常用数学计算
    神经网络相关术语
    keras初探
    机器学习相关
    Numpy random arange zeros
    numpy 常用函数
    【Redis学习之四】Redis数据类型 string
  • 原文地址:https://www.cnblogs.com/FYH-SSGSS/p/6918461.html
Copyright © 2011-2022 走看看