整數劃分問題(動態規劃)

果7發表於2013-11-05

題目描述:給你一個整數n,比如是4,輸出可以將4劃分的總數目。

可以劃分為

4

3 1

2 2     2 1 1 

1 1 1 1 

這樣總共有五種情況。


書上寫的是遞迴實現的方法,很耗費時間,輸入100之後還需要5s+的樣子才能執行出來。


可以直接使用動態規劃。 a[n][m]表示總和為n,其中最大的數字是m的總類數。我們所需要求得答案便是a[n][n].


(1)a[n][n]=a[n][n-1]+1

(2)a[n][m]=a[n][m-1]+a[n-m][m]  (m<n&&n-m>=m)    n-m是因為要使得這一行最大數字必須為m

(3)a[n][m]=a[n][m-1]+a[n-m][n-m]  (m<n&&n-m<m)



程式碼:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long a[1002][1002];

int fun(int n,int m)   //遞迴實現太耗費時間
{
    if(n<1||m<1) return 0;
    else if(n==1||m==1) return 1;
    else if(n<m) return fun(n,n);
    else if(n==m) return 1+fun(n,n-1);
    else return fun(n,m-1)+fun(n-m,m);
}

int main()
{
    int n,i,j;
    memset(a,0,sizeof(a));
    for(i=1;i<=1000;i++)
        a[i][1]=a[1][i]=1;
    for(i=2;i<=1000;i++)
    {
        for(j=2;j<i;j++)
        {
            if(i-j>=j) a[i][j]=a[i][j-1]+a[i-j][j];
            else a[i][j]=a[i][j-1]+a[i-j][i-j];
        }
        a[i][i]=a[i][i-1]+1;
    }

    while(cin>>n)
    {
        //cout<<fun(n,n)<<endl;
        cout<<a[n][n]<<endl;
    }
    return 0;
}



相關文章