1. 程式人生 > >NYOJ-90整數劃分

NYOJ-90整數劃分

整數劃分

時間限制:3000 ms  |  記憶體限制:65535 KB

難度:3

描述

將正整數n表示成一系列正整數之和:n=n1+n2+…+nk, 
其中n1≥n2≥…≥nk≥1,k≥1。 
正整數n的這種表示稱為正整數n的劃分。求正整數n的不 
同劃分個數。 
例如正整數6有如下11種不同的劃分: 
6; 
5+1; 
4+2,4+1+1; 
3+3,3+2+1,3+1+1+1; 
2+2+2,2+2+1+1,2+1+1+1+1; 
1+1+1+1+1+1。 

輸入

第一行是測試資料的數目M(1<=M<=10)。以下每行均包含一個整數n(1<=n<=10)。

輸出

輸出每組測試資料有多少種分法。

樣例輸入

1
6

樣例輸出

11

來源

上傳者

苗棟棟
思路:有三種做法

第一種:水過去,反正資料範圍小可以直接算出來

程式碼:

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define chu(a,b) memset(a,b,sizeof(a))
#define T() int test;scanf("%d",&test);while(test--)
const int maxn=2010;
const int inf=0x3f3f3f3f;
int dp[maxn][maxn];
int a[maxn],b[maxn];
int sum[maxn];
int an[]={1,2,3,5,7,11,15,22,30,42};
int main()
{
    T()
    {
        int n,i,j,k;
        scanf("%d",&n);
        printf("%d\n",an[n-1]);
    }
    return 0;
}

第二種:遞迴這種也好理解

程式碼:

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define chu(a,b) memset(a,b,sizeof(a))
#define T() int test;scanf("%d",&test);while(test--)
const int maxn=2010;
const int inf=0x3f3f3f3f;
int dp[maxn][maxn];
int a[maxn],b[maxn];
int sum[maxn];
int ans=0;
int ff(int k,int s)
{
    if(k==1||s==1)
        return 1;
   if(k==s)
   return 1+ff(k,s-1);
   if(k<s)
    return ff(k,k);
   if(k>s)
    return ff(k-s,s)+ff(k,s-1);
}
int main()
{
    T()
    {
        int n,i,j,k;
        scanf("%d",&n);
       printf("%d\n",ff(n,n));
    }
    return 0;
}

第三種:區間DP

思路:

陣列dp[N][M]表示N為被劃分數,M為劃分數的最大值,此題M==N,故即求dp[N][N];

1>狀態轉移方程:

dp[N][M]=dp[N][M-1]+dp[N-M][M];

該怎樣理解呢?這裡分兩步:

Step 1:所劃分的最大數不包括M,即每個劃分數都是小於M的,此時總數為dp[N][M-1].

Step 2:所劃分的最大數包括M,那麼這一步被劃分數就應該減去一個M,此時總數為dp[N-M][M].

程式碼:

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define chu(a,b) memset(a,b,sizeof(a))
#define T() int test;scanf("%d",&test);while(test--)
const int maxn=2010;
const int inf=0x3f3f3f3f;
int dp[maxn][maxn];
int a[maxn],b[maxn];
int sum[maxn];
void input()
{
    int i,j;
    for(i=1; i<=10; i++)
    {
        for(j=1; j<=10; j++)
        {
            if(i==j)
                dp[i][j]=1+dp[i][j-1];
            else if(i<j)
                dp[i][j]=dp[i][i];//因為只能是從大到小,所以當j大於i的時候等於dp[i][i]
            else
                dp[i][j]=dp[i][j-1]+dp[i-j][j];//小於的時候,j還可以再分
        }
    }
}
int main()
{
    input();
    T()
    {
        int n,i,j,k;
        scanf("%d",&n);
        memset(dp,0,sizeof(dp));
        printf("%d\n",dp[n][n]);
    }
    return 0;
}

相關推薦

NYOJ 90 整數劃分(遞推||dp)

整數劃分 時間限制:3000 ms  |  記憶體限制:65535 KB 難度:3 描述將正整數n表示成一系列正整數之和:n=n1+n2+…+nk,  其中n1≥n2≥…≥nk≥1,k≥1。

nyoj 90 整數劃分【dp劃分數】

整數劃分 時間限制:3000 ms  |  記憶體限制:65535 KB 難度:3 描述將正整數n表示成一系列正整數之和:n=n1+n2+…+nk,  其中n1≥n2≥…≥nk≥1,k≥1。  正整數n的這種表示稱為正整數n的劃分。求正整數n的不  同劃分個數。

nyoj 90 整數劃分(一) (dp||遞迴)

將正整數 n 表示成一系列正整數之和, n=n1+n2+…+nk, 其中 n1>=n2>=…>=nk>=1 , k>=1 。 正整數 n 的這種表示稱為正整數 n 的劃分。正整數 n 的不同的劃分個數稱為正整數 n 的劃分數,記作 p(n) 。 例如正整數 6 有如下 11

NYOJ 90整數劃分

整數劃分 時間限制:3000 ms  |  記憶體限制:65535 KB 難度:3 描述將正整數n表示成一系列正整數之和:n=n1+n2+…+nk,  其中n1≥n2≥…≥nk≥1,k≥1。  正整數n的這種表示稱為正整數n的劃分。求正整數n的不  同劃分個數。 

NYOJ-90整數劃分

整數劃分 時間限制:3000 ms  |  記憶體限制:65535 KB 難度:3 描述 將正整數n表示成一系列正整數之和:n=n1+n2+…+nk,  其中n1≥n2≥…≥nk≥1,k≥1。  正整數n的這種表示稱為正整數n的劃分。求正整數n的不  同劃分個數。 

NYOJ 746 整數劃分(四)區間DP

/* 區間dp,設dp[i][j] 表示在區間[0, i]之中,插入j個乘號可以得到的最大數 設a[i][j]為區間[i,j]所形成的數 所以 dp[i][j] = max(dp[k][j-1] * a[k + 1][i]) 注意數的範圍,用int不夠 */ #include <cmath>  

整數劃分dp(總結)】nyoj 571 整數劃分

 整數劃分(一)(二)(三)(四)(五)後接分析 /* 整數劃分 (一)將n劃分成若干不同整數之和的劃分數 (二)將n劃分成若干正整數之和的劃分數 (三)將n劃分成k個正整數之和的劃分數 (四)將n劃分成最大數不超過k的劃分數 (五)

整數劃分 nyoj 90

整數劃分 時間限制:3000 ms  |  記憶體限制:65535 KB 難度:3 描述將正整數n表示成一系列正整數之和:n=n1+n2+…+nk,  其中n1≥n2≥…≥nk≥1,k≥1

nyoj 整數劃分 90 (母函式)

整數劃分 時間限制:3000 ms  |           記憶體限制:65535 KB 難度:3 描述 將正整數n表示成一系列正整數之和:n=n1+n2+…+nk, 其中n1≥n2≥…≥nk≥1,k≥1。 正整數n的這種表示稱為正整數n的劃分。求正整數n的不

nyoj 整數劃分(一)(二)

先來談談寫這兩道題的感受,整數劃分(一)剛開始做這道題,dp和遞迴都不會寫,是用深搜寫的,不過用深搜寫 整數劃分(二)就不行了,鐵定超時。 昨晚和今晚終於把這兩道題的遞迴和dp全看懂了(看別人部

NYOJ 整數劃分

整數劃分 時間限制:3000 ms | 記憶體限制:65535 KB 難度:3 描述 將正整數n表示成一系列正整數之和:n=n1+n2+…+nk, 其中n1≥n2≥…≥nk≥1,k≥1。 正整數n的這種表示稱為正整數n的劃分。求正整數n的不 同劃分個數。 例如正整數

NYOJ 整數劃分(四) (區間dp)

題意:給出兩個整數 n , m ,要求在 n 中加入m - 1 個乘號,將n分成m段,求出這m段的最大乘積思路:區間dp,我們需要先預處理出第i位到第j位可以湊成的數sum[i][j],之後dp[i][j]表示你在第i個數字添加了j個乘號時的最大值,那麼dp[i][j] =m

(dp)openjudge 復雜的整數劃分問題

con fin can == names 劃分數 algorithm 系列 問題 將正整數n 表示成一系列正整數之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。正整數n 的這種表示稱為正整數n 的劃分。

整數劃分問題(二)

pro col void ++ cal -c 一行 測試 不同的 總時間限制:200ms內存限制:65536kB描述 將正整數n 表示成一系列正整數之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。正整數n

整數劃分問題

區別 不同 style back blog 表示 n-1 由於 思路 1.將n個不同的數字組成的集合劃分成若幹個元素和不大於m的集合: 1).若是劃分多個可重復整數: dp[n][m]= dp[n][m-1]+ dp[n-m][m] dp[n][m]表示

51nod 1201 整數劃分 dp

bit eps 不同的 color quest stream 空間 output lac 1201 整數劃分 基準時間限制:1 秒 空間限制:131072 KB 收藏 關註 將N分為若幹個不同整數的和,有多少種不同的劃分方式,例如:

動態規劃_百煉 4117 簡單的整數劃分問題

出口 sta pre color 劃分 stack 大於 iostream 規劃 1 #define _CRT_SECURE_NO_WARNINGS 2 #include <stdio.h> 3 #include <math.h> 4

Bzoj-1263[SCOI2006]整數劃分

num cst -a bsp post str class span names 要知道:用n個a和m個b可以組合出$(a*b-a-b)$以上的所有數(Noip2017 Day1T1) 以下給出證明(From onion_cyc): 所以我們可以知道2和3能夠組合成

poj 1664 整數劃分

http image ace stream 圖片 分享 count 技術分享 nbsp 根據題意,將n個蘋果放入m個盤子中,盤子樣式相同,求所有方法。 這是一個典型的整數劃分問題 1.n == 1 只有一個蘋果,由於盤子樣式相同,那麽放在哪個盤子中都是一種放法,fu

牛客網練習賽18 A 【數論/整數劃分得到乘積最大/快速乘】

vector owb gcd algorithm CI -- ostream 最大的 sig 鏈接:https://www.nowcoder.com/acm/contest/110/A 來源:牛客網 題目描述 這題要你回答T個詢問,給你一個正整數S,若有若幹個正整數的和為S