一个正整数N可以分解为M(M>1)个正整数的和,即N=K+L,例如N=5、M=2时可以分解为(1+4,2+3)。
给定一个正整数N(1<N<200)及正整数M(1<M<200),求有多少种可能的分解组合(注:K+L和L+K算一种)
#include<iostream> #include<bits/stdc++.h> using namespace std; int main(void){ int n, m; while(~scanf("%d,%d", &n, &m)){ //6,3 int dp[m+1][n+1][n+1]; //dp[i][j][k]由i个元素组成,和为j,且最大元素为k的组合个数 memset(dp,0,sizeof(dp)); // 初始化 for(int i=1; i<=n; ++i) dp[1][i][i] = 1; // 取第i个元素 for(int i=2; i<=m; ++i){ // 更新取了i个元素,和为j的情况 for(int j=1; j<=n; ++j){ // 假设第i个元素取了k for(int k=1; k<=j; ++k){ // 第i个元素取k是最大值 dp[i][j][k] += (dp[i-1][j-k][k]); // 第i个元素取k但不是最大值的情况 for(int z=1; z<k; ++z) dp[i][j][k] += dp[i-1][j-k][z]; } } } int res = 0; for(int i=n; i>=0; --i) if ( dp[m][n][i]>0 ) res += dp[m][n][i]; cout<<res<<endl; } }
n,m = map(int, input().split(",")) dic = {} def loop(n, m): if (m == 1)&nbs***bsp;(n - m == 1)&nbs***bsp;(n == m): dic[(n, m)] = 1 elif m == 2: dic[(n, m)] = int( n / 2) else: left, i, total = n - m, 1, 0 while left >= i and i <= m: if (left, i) in dic.keys(): total = total + dic[(left, i)] i = i + 1 else: loop(left, i) dic[(n, m)] = total loop(n,m) print(dic[(n,m)])
def GetTypeNum(n,k): n = n-1 #间隔总数 k = k-1 #需要的分割的间隔数 if n%2 == 0: half = int(n/2) if n%2 != 0: half = int((n+1)/2) j = [] for i in itertools.combinations(range(1,half+1), k): #无放回不重复抽样 li = list(i) j.append(li) return len(j)用了排列组合的思想 比如:N=5,M=2 5=1+1+1+1+1 1与1之间共有4个间隔(标记为①,②,③,④) 需要用M-1=1个间隔可以将数据分解成M=2份 但是间隔需要折半(偶数除以2 奇数先加1再除以2) 插在间隔①位置为1+4 插在间隔④位置为4+1(题中说K+L和L+K算一种) 折半4/2=2后再无放回不重复抽样 每次抽2-1个间隔 即C21
data= [int(x) for x in input().split(',')] N=data[0] K=data[1] def Data(data,min_,k): if k==1: if data>=min_: return 1 else: return 0 else: temp=0 for i in range(min_,data//k+1): temp+=Data(data-i,i,k-1) return temp print(Data(N,1,K))感觉应该用动态规划,理解了一下楼里大佬的,稍稍修改,另外加了注释。就100%通过了
data= [int(x) for x in input().split(',')] N=data[0] K=data[1] def Data(data,k): #k拆分 if data<k: return 0 #楼里大佬的问题,没判断无法划分的问题。。。 else: if k==1: return 1 else: D={} D[0,0]=0 for i in range(1,data+1): for j in range(1,min(i+1,k+1)): if j==1: D[i,j]=1 else: D[i,j]=D[i-1,j-1] #D[i,j]=D[i-j,j]+D[i-1,j-1] if i>=2*j: #意思是分割有两种情况:不包含1和包含1,当然可能不一定包含1 D[i,j]+=D[i-j,j] return D[data,k] print(Data(N,K))
def solve(n, m): for i in range(2, n + 1): for j in range(2, i + 1): dic[(i, j)] = dic[(i - 1, j - 1)] if i >= 2*j: dic[(i, j)] += dic[(i - j, j)] n, m = map(int, input().split(',')) if n < m: print(0) else: dic = dict() dic[(0, 0)] = 1 for k in range(1, n + 1): # 将k分解为1个正整数只有一种组合 dic[(k, 1)] = 1 solve(n, m) print(dic[(n, m)])
n,m = map(int,input().split(",")) dic = {} dic[(0,0)] = 1 for k in range(1,n+1): dic[(k,1)] = 1 def loop(n, m): for i in range(2,n+1): for j in range(2,i+1): dic[(i,j)] = dic[(i-1,j-1)] if (i >= 2*j): dic[(i,j)] += dic[(i-j,j)] loop(n,m) print(dic[(n,m)])
# 分拆数p(n,k) integer partition # $p(n,k)=p(n-1,k-1)+p(n-k,k)$ n,k=map(int,input().split(",")) p=[[0 for i in range(1000)]for j in range(1000)] p[0][0]=1 p[1][1]=1 p[1][2]=0 for i in range(1,n+1): for j in range(1,i+1): p[i][j]=p[i-1][j-1]+p[i-j][j] print(p[n][k])
N, K= list(map(int, input().split(','))) #输入数据 memo = dict() #词典备忘录,避免重复计算 def re(n, m): global memo if n==m&nbs***bsp;m==1: #边界条件 return 1 if n<m: #边界条件 return 0 res = 0 for i in range(1, min(n-m, m)+1): # if (n-m, i) in memo: res = res + memo[(n-m, i)] #查看备忘录中是否有记录 else: res = res + re(n-m, i) #状态转移方程 memo[(n, m)] = res #存入备忘录 return memo[(n, m)] print(re(N, K))
N, K = list(map(int,input().strip(' ').split(','))) dic = {} def recur(N,K): if N==K&nbs***bsp;N==K+1&nbs***bsp;K==1: return 1 if K == 2: return (N//2) res = 0 for i in range(1,min(N-K,K)+1): if (N-K,i) in dic: res += dic[(N-K,i)] else: res += recur(N-K,i) dic[(N,K)] = res return res print(recur(N,K))
N, M = list(map(int,input().strip(' ').split(','))) dic = {} def DP(n,m): """ n-----目前有的数 m-----目前的次数 n-m---剩余需要处理的数 """ global dic if n == m or n - m == 1 or m == 1: dic[(n,m)] = 1 return if m == 2 and n >= m: dic[(n,m)] = int(n // 2) return i = 1 res = 0 while i <= n-m and i <= m: if (n-m,i) in dic: res += dic[(n-m,i)] i += 1 else: DP(n-m,i) dic[(n,m)] = res return DP(N,M) print(dic[(N,M)])
C++回溯通过70%
#include <vector> #include <iostream> using namespace std; void dfs(int total, int len, vector<int>&temp, int & res, int cur, int sum){ if(temp.size() >= len) return; if(temp.size() == len-1) res++; for(int i = cur; i <= (total - sum)/(len - temp.size()); i++){ temp.push_back(i); int store = i; sum += store; dfs(total, len, temp, res, i, sum); sum -= store; temp.pop_back(); } } int solution(int total, int len){ int res = 0; vector<int> temp; dfs(total, len, temp, res, 1, 0); return res; } int main(){ char temp; int total, len; cin >> total >> temp >> len; cout << solution(total, len); return 0; }
from itertools import combinations m0=[] a0=[] def GetTypeNum(n,k): j = [] for i in combinations(range(0,n-1), k-1): j.append(i) for i in range(len(j)): a=[] for t in range(len(j[i])-1): a.append(j[i][t+1]-j[i][t]) a.insert(0,j[i][0]+1) a.append(int(n-j[i][len(j[i])-1])) a.sort() a0.append(a) newList = [] for x in a0: if x not in newList : newList.append(x) return(len(newList)) if __name__ == '__main__': n,k =list(map(int,input().split(','))) print(GetTypeNum(n,k)-1)超时了2333。。。没想到去重的好办法。。。
#include <iostream> using namespace std; int main() { char temp; int n, m; cin >> n >> temp >> m; //dp[n][m]= //1,n=1,m=1 //q(n,n) n<m //1+q(n,n-1) n=m //q(n,m-1)+q(n-m,m) n>m>1 int dp[201][201];//dp[i][j]表示把i拆分,最大的数不超过j的排列。 for (int i = 0; i <= n; i++) { dp[i][0] = 0; } for (int i = 0; i <= m; i++) { dp[0][i] = 0; } for (int i = 1; i <= n; i++) { dp[i][1] = 1; } for (int i = 1; i <= m; i++) { dp[1][i] = 1; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (i < j) { dp[i][j] = dp[i][i]; } else if (i == j) { dp[i][j] = 1 + dp[i][i - 1]; } else { if (i - j < 1) { dp[i][j] = dp[i][j - 1]; } else { dp[i][j] = dp[i][j - 1] + dp[i - j][j]; } } } } cout << dp[n][m]- dp[n][m - 1]; return 0; }