zoukankan      html  css  js  c++  java
  • [bzoj4894]天赋

    来自FallDream的博客,未经允许,请勿转载,谢谢。


    小明有许多潜在的天赋,他希望学习这些天赋来变得更强。正如许多游戏中一样,小明也有n种潜在的天赋,但有一些天赋必须是要有前置天赋才能够学习得到的。也就是说,有一些天赋必须是要在学习了另一个天赋的条件下才能学习的。比如,要想学会"开炮",必须先学会"开枪"。一项天赋可能有多个前置天赋,但只需习得其中一个就可以学习这一项天赋。上帝不想为难小明,于是小明天生就已经习得了1号天赋-----"打架"。于是小明想知道学习完这n种天赋的方案数,答案对1,000,000,007取模。
    n<=300
     
    出题人的语文水平不是很好  两种方案不同其实是有一个天赋的前置天赋不同。
    这样就变成了树形图计数,矩阵数定理,高斯消元即可。
    复杂度O(n^3)
    #include<iostream>
    #include<cstdio>
    #define MN 300
    #define mod 1000000007
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    char st[MN+5][MN+5];
    int n,s[MN+5][MN+5],ans=1;
    
    int pow(int x,int k)
    {
        int sum=1;
        for(;k;k>>=1,x=1LL*x*x%mod)
            if(k&1) sum=1LL*sum*x%mod;
        return sum;
    }
    
    void Gauss(int N)
    {
        for(int i=2;i<=N;++i)
        {
            for(int j=i;j<=N;++j)
                if(s[j][i]) 
                {
                    if(j!=i) 
                    {
                        ans=mod-ans;
                        for(int k=i;k<=N;++k)
                            swap(s[j][k],s[i][k]);
                    }
                    break;    
                }
            int Inv=pow(s[i][i],mod-2);
            for(int j=i+1;j<=N;++j)
                if(s[j][i])
                {
                    int inv=1LL*Inv*s[j][i]%mod;
                    for(int k=i;k<=N;++k)
                        s[j][k]=(s[j][k]-1LL*inv*s[i][k]%mod+mod)%mod;
                }
        }
        for(int i=2;i<=N;++i) ans=1LL*ans*s[i][i]%mod;    
    }
    
    int main()
    {
        n=read();if(n==1) return 0*puts("1");
        for(int i=1;i<=n;++i)
        {
            scanf("%s",st[i]+1);
            for(int j=1;st[i][j];++j)
                if(st[i][j]=='1') ++s[j][j],(s[i][j]+=mod-1)%=mod;    
        }
        Gauss(n);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    LeetCode449. 序列化和反序列化二叉搜索树
    LeetCode448. 找到所有数组中消失的数字
    一行代码如何隐藏 Linux 进程?
    C语言这么厉害,它自身又是用什么语言写的?
    了解C语言,是否代表了解C ++的一半?
    C语言小白那些不知道的事儿
    6 条 Git 实用技巧
    干货来袭,收藏方便找到该网站
    零基础小白如何入门Shell,快来看看(收藏)这篇大总结!!
    Java用于嵌入式系统的优点和局限
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj4894.html
Copyright © 2011-2022 走看看