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