XTU 1090组合数

Description

2n=C(n,0)+C(n,1)+…+C(n,n)。其中表示幂,C(n,x)表示组合数,即C(n,x)=n!/((n-x)!x!)。现在给你n(0<=n<=33),要你输出2^n的组合数之和的表达式

输入

每行一个整数n,如果n为负数则输入结束。

输出

每行输出一个表达式,表达式格式形似为2^n=C(n,0)+C(n,1)+…+C(n,n)。

Sample Input

2

3

-1

Sample Output

2^2=1+2+1

2^3=1+3+3+1

思路

传统方法计算组合数需要计算阶乘,非常容易溢出。经测试,开long long算到21就溢出了。题上要求算到33。
google之后发现可以用杨辉三角,用空间代替时间。(但是如果空间要求很严格可能就要用大数计算了)
杨辉三角:
即第i行的第j个数等于第i-1行的第j-1个数与第j个数之和,用二维数组形式表达即为a[i][j] = a[i-1][j-1] + a[i-1][j]。
代码实现

void YangHui() {
    memset(Triangle, 0, sizeof(Triangle));
    for (int i=0; i<n; ++i) {
        Triangle[i][0]=1;
        for (int j=1; j<n; ++j) Triangle[i][j]=Triangle[i-1][j-1]+Triangle[i-1][j];
    }
}

杨辉三角打印好之后只需要查表即可得到组合数,此题只算到33,我也只打印到33行。杨辉三角第i行第j列即为i中选j的组合数。

代码:(为了练习c++所以用向量做的,其实用数组更简便点)

# include<iostream>
# include<vector>

using namespace std;

int main()
{
    vector<vector<long long> > yangh(34);
    yangh.resize(34);
    for (int i = 0; i < yangh.size(); i++)
        yangh[i].resize(34);
    for(int i=0;i<34;i++)
    {
        yangh[i][0]=yangh[i][i]=1;
        for(int j=1;j<i;j++)
            yangh[i][j]=(yangh[i-1][j]+yangh[i-1][j-1]);
    }
    int n;
    while(cin>>n&&n>=0)
    {
        cout<<"2^"<<n<<"=";
        vector<long long> ans;
        for(int i=0;i<=n;i++)
            ans.push_back(yangh[n][i]);
        vector<long long>::iterator it;
        for(it=ans.begin();it!=ans.end();it++)
        {
            cout<<*it;
            if(it!=ans.end()-1) cout<<"+";
        }
        cout<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/oslowwalker/article/details/83090341