(AcWing) 900. División entera (Recuento DP)

Un número entero positivo n se puede expresar como la suma de varios números enteros positivos, como: n=n1+n2+...+nk, donde n1≥n2≥...≥nk, k≥1.

A esta representación la llamamos división del entero positivo n.

Ahora, dado un entero positivo n, averigüe cuántos métodos de división diferentes existen para n.

formato de entrada

Una línea que contiene un número entero n.

formato de salida

Un total de una línea, que contiene un número entero, que indica el número total de divisiones.

Dado que la respuesta puede ser muy grande, tome el módulo 10^9+7 para obtener el resultado.

rango de datos

1≤n≤1000

Muestra de entrada:

5

Salida de muestra:

7

Método 1: PD

 

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010, mod = 1e9 + 7;

int n;
int f[N];

int main()
{
    cin >> n;

    f[0] = 1;
    //f[i]是从前i个物品中选取物品的 总体积<=背包总体积n的方法数
    //f[0]是体积为0的背包然后所有都不选是一种方案,
    //一个数都不选,总和是0,是一种方案f[i][0],前i个数中选,总和恰好等于0,只有一种都不选这种方案
    
    
    for (int i = 1; i <= n; i ++ )
        for (int j = i; j <= n; j ++ )
            f[j] = (f[j] + f[j - i]) % mod;
    //f[i][j] = f[i-1][j] + f[i][j-i]
    //          (不选i)    (选i)

    cout << f[n] << endl;

    return 0;
}

 Método 2:

 

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010, mod = 1e9 + 7;

int n;
int f[N][N];

int main()
{
    cin >> n;
    f[0][0] = 1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            f[i][j] = (f[i-1][j-1]+f[i-j][j])%mod;
        }
    }
    
    int res = 0;
    for(int i=1;i<=n;i++) res=(res+f[n][i])%mod;
    cout<<res<<endl;
}

 Método 3:

#include <iostream>  
using namespace std;  
// Author: bjr  
//   
const int max = 1000;   
// sup是保存多项式的数组,sup[n]中的值代表xn的系数
// temp是临时多项式,保存相乘的临时中间情况  
int sup[max], temp[max];   
/*
程序始终只计算两个多项式之间的乘积,多个多项式的情况
先计算前两个的乘积,将结果作为第一个多项式,再与第三个相乘
依次类推,sup始终存放当前运算后的结果然后作为被乘多项式,
*/  
int main()  
{   
    int target;   //  目标重量, 比如上面的例子里就是10,要<max的值
    int i, j, k;  
   
    while(cin >> target)  
    {  
        for(i=0; i<=target; ++i)     
        {  
            sup[i] = 1;   
//初始化第一个多项式,也就是用1g砝码的多项式,
//注意如果题目没给1g的砝码那么就不能++i,而要加上砝码的质量
            temp[i] = 0;  
//将临时区清空,无论第一个多项式质量是几都要全部置零
        }  
        for(i=2; i<=target; ++i)   
// 生成后续的第i个多项式,此题中是2g,i从2开始。
//如果砝码的值不是规律增长,i可能需要取决于输入
        {  
   
            for(j=0; j<=target; ++j)   
// 遍历当前结果多项式的每一项(当前结果的第j项)与第i个多项式相乘,
                for(k=0; k+j<=target; k+=i) 
// 遍历第i个多项式的每一项,此处构造用小砝码组成大砝码的多项式
                {  
                    temp[j+k] += sup[j];  
//幂运算,注意理解
                }  
            for(j=0; j<=target; ++j)    
// 将临时的结果覆盖当前结果,同时把临时结果置零,为下次做准备
            {  
                sup[j] = temp[j];  
                temp[j] = 0;  
            }  
        }  
        cout << sup[target] << endl;  //输出结果
    }  
    return 0;  
}  

 Reimpreso en: El principio y la implementación de la función madre ordinaria_Taishang insensible blog-CSDN blog

Supongo que te gusta

Origin blog.csdn.net/GF0919/article/details/132428187
Recomendado
Clasificación