C++ 【NOIP2011】计算系数——利用另类DP巧解

题目描述

给定一个多项式(ax + by)^k,请求出多项式展开后x^n y^m项的系数。

输入

输入文件名为 factor.in。
共一行,包含 5 个整数,分别为a,b,k,n,m,每两个整数之间用一个空格隔开。

输出

输出文件名为 factor.out。
输出共 1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007 取
模后的结果。

样例输入

Copy (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

factor.in 
1 1 3 1 2

样例输出

factor.out
3

提示

【数据范围】

对于 30%的数据,有0≤k≤10;

对于 50%的数据,有a = 1,b = 1;

对于 100%的数据,有0≤k≤1,000,0≤n, m≤k,且n + m = k,0≤a,b≤1,000,000。


思路讲解

这道题可以用组合数直接得解,但这里用了另一个方法,利用杨辉三角进行的DP求解

用 f [ i ][ j ] 表示 a^{i-1}b^{j-1}系数,则会有 f [ 1 ][ 1 ] = 1 , 则 f [ 1 ][ 2 ]  表示 a^{0}b^{1}的系数, f [ 2 ][ 1 ] 表示a^{1}b^{0}的系数, f [ 3 ][ 1 ] 表示 a^{2}b^{0}dexi的系数,根据杨辉三角的性质,a^{i}b^{j} =a^{i-1}b^{j}+a^{i}b^{j-1},则有 f [ i ][ j ] = f [ i - 1 ][ j ] +f[ i ][ j - 1 ] ,这只是针对其系数为一的情况,那该怎样做呢,对于(ax+by)^{2},则为 f [ i ][ j ] = f [ i - 1 ][ j ] * a +f[ i ][ j - 1 ] * b ,但在编程实践中要注意不要数组越界


代码

结合代码理解

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
   
int a , b , k , m , n ;
long long f[1007][1007] ;
   
int main()
{
    scanf("%d%d%d%d%d", &a , &b , &k , &n , &m );
    f[1][1] = 1 ;//零次方的系数 
    for(int i = 1 ; i <= n +1; ++ i )
    {
        for(int j = 1 ; j <= m +1; ++ j )
        {
            if( i == 1 && j == 1 )
                continue;
            f[i][j] = 0;
            if( i > 1 )//防止数组的越界
                f[i][j] = (f[i][j] + f[i-1][j] * a ) % 10007;//系数都要乘上 a 或 b 
            if( j > 1 )
                f[i][j] = (f[i][j] + f[i][j-1] * b ) % 10007;
        } 
    }
    cout<<f[n+1][m+1];
}

猜你喜欢

转载自blog.csdn.net/qq_44013342/article/details/87971763