HDU 1028 Ignatius and the Princess III

本文介绍了一种使用动态规划解决将正整数分解为若干正整数和的方法,并对比了递归和递推两种实现方式的时间效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        题意:把一个正整数N表示为若干个正整数的和,输出有多少种表示方法。

        思路:DP

        思考过程是这样的。设a[1]>=a[2]>=a[3]...,因为N=a[1]+a[2]+a[3]+...。N减去a[1]后,N-a[1]成为了原问题的一个子问题。开一个二维数组DP[122][122],DP[N][M]表示正整数N的最大加数为M的分解方法数。


递归法+存储结果(0ms):

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <ctype.h>

using namespace std;

int DP[122][122];

int solve(int n,int m){
    if(n==0)return 1;
    if(DP[n][m])return DP[n][m];
    int res=0;
    for(int i=1;i<=m;i++){
        if((n-i)<0)break;
        res+=solve(n-i,i);
    }
    DP[n][m]=res;
    return res;
}

int main(){
    int n;
    memset(DP,0,sizeof(DP));
    while(~scanf("%d",&n)){
        cout<<solve(n,n)<<endl;
    }
    return 0;
}

递推法(15ms):

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <ctype.h>

using namespace std;

int DP[122][122];


int solve(){
    for(int i=0;i<122;i++){
        DP[0][i]=1;
    }
    for(int i=1;i<122;i++){
        for(int j=0;j<122;j++){
            for(int k=0;k<=j;k++){
                if((i-k)<0)break;
                DP[i][j]+=DP[i-k][k];
            }
        }
    }
}

int main(){
    int n;
    memset(DP,0,sizeof(DP));
    solve();
    while(~scanf("%d",&n)){
        cout<<DP[n][n]<<endl;
    }
    return 0;
}

        有点意外的是递归竟然比递推快,可能是递推把所有结果都计算了一遍,而递归没有,要么就是我的实现还不够好。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值