• 【NOIP2011提高组】计算系数


    计算系数

    算法:真·滚动数组模拟!!!

    马上CSP/S了,这是远在今年暑假前的一天的校内考试题中的一道。当时做的时候不会组合数,不会二项式定理,不会DP,不会……只知道应该n*n的空间存一个杨辉三角形图,然后依次读取。

    然而考场上发现这个可以优化,并滚键盘滚出了下面的那一坨东西居然对了:只需2个数组就可以存下整个题目所需要的杨辉三角形:杨辉三角形的长度和k有关,比如:

    3——1 2 1,长度3

    4——1 3 3 1,长度4

    ……

    可见k为奇数,则杨辉三角形长度为奇数,反之为偶数。

    我们要求第k层的杨辉三角形。在计算的过程中,下一层需要从上一层的杨辉三角形转移而来(dp思想?!),而上下两层奇偶不同,其长度必然不同,于是我们用2个数组不停滚动,就能正确求得要的那层杨辉三角形。

    #include<bits/stdc++.h>
    using namespace std;
    int f1=1,f2=1,a,b,k,n,m,ans,yh[1005]= {0,1},yh2[1005]= {0,1};
    void yanghui(int x)
    {
        if(x%2==0)//层数为偶数
            for(int i=2; i<=x+1; i++)//为什么i=2开始?因为杨辉三角形每层的第一个数必定是1
                yh2[i]=(yh[i-1]+yh[i])%10007;//从上一层下来
        else if(x%2==1)//层数为奇数
            for(int i=2; i<=x+1; i++)
                yh[i]=(yh2[i-1]+yh2[i])%10007;//同上
        if(x+1!=k)yanghui(x+1);//只要层数不到k,我们就继续转移
    }
    int fang()
    {
        for(int i=1; i<=n; i++)
            f1=(f1*a)%10007;
        for(int i=1; i<=m; i++)
            f2=(f2*b)%10007;
        return (f1*f2)%10007;
       //朴素乘运算。有兴趣你可以造个快速幂什么的
    }
    int main()
    {
        //freopen("factor.in","r",stdin);
        //freopen("factor.out","w",stdout);freopen注释
        scanf("%d%d%d%d%d",&a,&b,&k,&n,&m);
        a=a%10007,b=b%10007;//千万要读入取模!!考场忘记取模80分,回家取模AC
        if(k==0||k==1)//特判2种情况
        {
            cout<<0;
            return 0;
        }
        k++;//请思考为什么要k++ k--
        yanghui(1);//制造杨辉三角形
        k--;
        if(k%2==1)ans=(fang()*yh[n+1])%10007;
        if(k%2==0)ans=(fang()*yh2[k-n+1])%10007;//计算系数,判断k的奇偶
        printf("%d",(ans+10007)%10007);
       //时时刻刻取余以保证代码正确性
       return 0;
    }

    注意:计算时时时刻刻取余以保证代码正确性!!!

    注意:读入a、b要取余!!!

  • 相关阅读:
    十. 代码格式化插件 Tag
    小知识点
    IE11 打开方式 出现两个图标
    一 OS X 焦点 切换
    九. 边栏工具 浏览器工具 SideBarEnhancements
    Django进阶之缓存和信号
    Django进阶之中间件
    Python 堡垒机编程之Paramiko
    Django ORM补充
    Web 开发基础之Html
  • 原文地址:https://www.cnblogs.com/yige2019/p/11844501.html
Copyright © 2020-2023  润新知