1. 程式人生 > >(dp)openjudge 復雜的整數劃分問題

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

con fin can == names 劃分數 algorithm 系列 問題

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

輸入標準的輸入包含若幹組測試數據。每組測試數據是一行輸入數據,包括兩個整數N 和 K。
(0 < N <= 50, 0 < K <= N)輸出對於每組測試數據,輸出以下三行數據:
第一行: N劃分成K個正整數之和的劃分數目
第二行: N劃分成若幹個不同正整數之和的劃分數目
第三行: N劃分成若幹個奇正整數之和的劃分數目樣例輸入

5 2

樣例輸出

2
3
3

提示第一行: 4+1, 3+2,
第二行: 5,4+1,3+2
第三行: 5,1+1+3, 1+1+1+1+1+1

雖然是3個問題,但其實都是通過討論1的是否存在推出的轉移方程。並且可以證明第二種和第三種的個數永遠是相等的。

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <queue>
 8 #include <set>
 9 #include <map>
10 #include <list>
11
#include <vector> 12 #include <stack> 13 #define mp make_pair 14 //#define P make_pair 15 #define MIN(a,b) (a>b?b:a) 16 //#define MAX(a,b) (a>b?a:b) 17 typedef long long ll; 18 typedef unsigned long long ull; 19 const int MAX=1e2+5; 20 const int INF=1e8+5; 21 using namespace std; 22 //const int MOD=1e9+7;
23 typedef pair<ll,int> pii; 24 const double eps=0.00000001; 25 26 int n; 27 int dp[MAX][MAX],dp2[MAX][MAX],dp3[MAX][MAX]; 28 int get_dp(int x,int y) 29 { 30 if(y>x) 31 return dp[x][y]=0; 32 if(dp[x][y]>=0) 33 return dp[x][y]; 34 if(y<=1) 35 return dp[x][y]=y; 36 return dp[x][y]=get_dp(x-y,y)+get_dp(x-1,y-1); 37 } 38 int get_dp2(int x,int y) 39 { 40 if(dp2[x][y]>=0) 41 return dp2[x][y]; 42 if(y*(y+1)/2>x) 43 return dp2[x][y]=0; 44 if(y<=1) 45 return dp2[x][y]=y; 46 return dp2[x][y]=get_dp2(x-y,y-1)+get_dp2(x-y,y); 47 } 48 int get_dp3(int x,int y) 49 { 50 if(dp3[x][y]>=0) 51 return dp3[x][y]; 52 if(y>x) 53 return dp3[x][y]=0; 54 if(y==0) 55 return dp3[x][y]=0; 56 if (y==1) 57 return dp3[x][y]=x%2; 58 return dp3[x][y]=get_dp3(x-1,y-1)+get_dp3(x-2*y,y); 59 } 60 int z; 61 int main() 62 { 63 memset(dp,-1,sizeof(dp)); 64 memset(dp2,-1,sizeof(dp2)); 65 memset(dp3,-1,sizeof(dp3)); 66 while(~scanf("%d%d",&n,&z)) 67 { 68 printf("%d\n",get_dp(n,z)); 69 int an=0; 70 for(int s=1;s<=n;s++) 71 { 72 int tem=get_dp2(n,s); 73 an+=tem; 74 } 75 int an2=0; 76 printf("%d\n",an); 77 for(int s=1;s<=n;s++) 78 { 79 int tem=get_dp3(n,s); 80 an2+=tem; 81 } 82 printf("%d\n",an,an2); 83 } 84 }

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