HDU 1028 Ignatius and the Princess III

来源:互联网 发布:软件测试需求文档 编辑:程序博客网 时间:2024/06/17 12:17

        题意:把一个正整数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;}

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



0 0