zoukankan      html  css  js  c++  java
  • 整理,模板

    组合数学、
    -排列组合数
    ----sum求
    sum=sum*(m--)/i;
    int c(int n,int m)//n下标,m上标
    {
        int sum=1;
        for(int i=1;i<=m;i++)
            sum=sum*(n--)/i;
        return sum;
    }
    ----二维数组递推(打表)
    #define maxx 1000
    int c[maxx+2][maxx+2];
    void init()//递推打表
    {
        memset(c,0,sizeof(c));
        c[0][0]=c[1][0]=c[1][1]=1;
        for(int i=2;i<maxx;i++)
        {
            c[i][i]=c[i][0]=1;
            for(int j=0;j<i;j++)
            {
                c[i][j]=(c[i-1][j-1]+c[i-1][j]);
            }
        }
    }
    ---原始公式(单个)数字太大,用分子分母约分,优化
    #define maxx 1000
    int c[maxx+2][maxx+2];
    void init()//递推打表
    {
        if(m>n-m) 
            m=n-m; 
        int temp=n; 
        for(int i=1;i<=m;i++)//根据组合公式把原始的分子分母分别存在数组中 
        { 
            up[i]=temp--; 
            down[i]=i; 
        } 
        for(int i=1;i<=m;i++)//外层循环代表分母,对分母依次进行约分 
            for(int j=1;j<=m;j++) 
            { 
                temp=gcd(down[i],up[j]); 
                if(temp>1) 
                { 
                    up[j]/=temp; 
                    down[i]/=temp; 
                } 
                if(down[i]==1)//分母已经为1,退出,进行下一个分母的约分 
                    break; 
            } 
        int sum=1; 
        for(int i=1;i<=m;i++) 
            sum=sum*up[i]/down[i]; 
        return sum;
    }
    -全排列模板
    -----生成全排列函数
    prev_permutation和next_permutation
    int main ()
    {
        int a[] = {1,2,3};
        do
        {
            cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<endl;
        }while(next_permutation(a,a+3));// 后一个排列组合

        return 0;
    }
    区别prev_permutation //前一个排列组合
    --母函数
    模板---用的时候一般会变一下数,式子中等阶指数(xiayige)
    --错排
    错位排列的公式有
    dn=n!(1-1/1!+1/2!-1/3!+...+(-1)^n*1/n!)
    还有一个递推的形式
    d[n]=(n-1)*(d[n-1]+d[n-2])
    void D() 

        for(int i=2;i<=20;i++) 
            d[i]=(i-1)*(d[i-1]+d[i-2]); 

    ---卡特兰数
    卡特兰数:
     1 通项公式:
    h(n)=C(n,2n)/(n+1)=(2n)!/((n!)*(n+1)!)
     2递推公式:
    h(n)=((4*n-2)/(n+1))*h(n-1); h(n)
           =h(0)*h(n-1)+h(1)*h(n-2)+...+h(n-1)*h(0).
    3前几项为:h(0)=1,h(1)=1,h(2)=2,h(3)=5,h(4)=14,h(5)=42,......

    欧拉函数
    φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),
    其中p1, p2……pn为x的所有质因数,x是不为0的整数。φ(1)=1
    求单个(公式地推)
    int phi(int n)//求phi(n)
    {
        int m=(int)sqrt(n+0.5);
        int ans=n;
        for(int i=2;i<=m;i++)
            if(n%i==0)
            {
                ans=ans/i*(i-1);
                while(n%i==0)
                    n/=i;
            }
        if(n>1)
            ans=ans/n*(n-1);
        return ans;
    }
    打表(筛法)
    #define maxn 32768
    int phi[maxn];
    void phi_table(int n)
    {
        for(int i=2;i<=n;i++)
            phi[i]=0;
        phi[1]=1;
        for(int i=2;i<=n;i++)
            if(!phi[i])
            for(int j=i;j<=n;j+=i)
            {
                if(!phi[j])
                    phi[j]=j;
                phi[j]=phi[j]/i*(i-1);
            }
    }
    背包
    01
    c[i][m]=max{c[i-1][m],c[i-1][m-w[i]]+p[i]}

    这个方程非常重要,基本上所有跟背包相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:“将前i件物品放入重量为m的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为c[i-1][m];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的重量为m-w[i]的背包中”,此时能获得的最大价值就是c[i-1][m-w[i]]再加上通过放入第i件物品获得的价值p[i]。


  • 相关阅读:
    Traefik-v2.x快速入门
    jenkins pipeline持续集成
    phpstorm 2017激活码(方法)
    PHP保留两位小数的几种方法
    php 数组排序 按照某字段
    sql大全
    解决jpgraph在php7.0版本下时,无法显示例子图表的问题
    Linux 定时任务crontab使用
    VIM命令操作
    wampserver变橙色,apache 服务无法启动!问题解决小记(安装失败亦可参考)
  • 原文地址:https://www.cnblogs.com/vivider/p/3701038.html
Copyright © 2011-2022 走看看