0
点赞
收藏
分享

微信扫一扫

计蒜客 -- 基础dp --划分整数

回溯 2023-02-17 阅读 100


蒜头君特别喜欢数学。今天,蒜头君突发奇想:如果想要把一个正整数 n 分解成不多于 k 个正整数相加的形式,那么一共有多少种分解的方式呢

蒜头君觉得这个问题实在是太难了,于是他想让你帮帮忙。

输入格式

共一行,包含两个整数 n(1≤n≤300) 和 k(1≤k≤300),含义如题意所示。

输出格式

一个数字,代表所求的方案数。

样例输入复制

5 3

样例输出复制

5

对于样例,55 有 55 种不大于 33 个数的相加方式, 分别是:

5 = 5

5 = 4 + 1

5 = 3 + 2

5 = 3 + 1 + 1

5 = 2 + 2 + 1

 

计蒜客 -- 基础dp --划分整数_ios

 dp [i][j] 表示将正整数 i  分解成 j 个正整数相加的方案数. 

 这种题目难就难在递推表达式的分析上 , 首先, 如果 n = 1 , 那么 不管k 取多少 只有 "  1 "  这种方案合法  , 如果  k = 1 , 不管 n 取值为多少只有 " n " 这种方案合法   ;   当 n  > k 时 拿 上面的例子来说 ,  n = 5 ,  k = 3  , 就是说 将整数 5 分解成 3个数 相加的方案数 , 分两种情况 , 正好能用 k 个数相加表示 n 的情况 和  用 少于 k 个数相加表示n 的情况 。前一种情况 这k 个数一定都 >=1 ,那么这k 个数每个数都减去 1 , 这时n 变成了 n-k , 也就是 正整数  n-k 用 k 个数相加表示 , 这时就等价于  n-k 用不少于 k 个数相加表示的方案数  ;  后一种情况 ,此时即dp[n][k-1],也就是将正整数n分解为不多于k-1个正整数相加的形式的方案数

当 n = k 的时候 ,n恰好分解为k个正整数相加的形式时,只有"n=n/k+n/k+...+n/k"这1种分解方案,故方案数=1+dp[n][k-1] . 

n < k 时 没有合法方案

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
const int MAX = 1005 ;
typedef long long LL ;
LL dp[MAX][MAX] ;

int main(){
int n , k ;
cin >> n >> k ;
for(int i = 1 ; i<=n ; i++) {
for(int j =1 ; j<=k ; j++ ) {
if(i == 1 || j ==1 ) {
dp[i][j] = 1 ;
}
else if(i < j){
dp[i][j] = dp[i][i] ;
}
else if(i > j){
dp[i][j] = dp[i][j-1] + dp[i-j][j] ;

}
else{
dp[i][j] = dp[i][j-1]+1 ;
}
}
}
cout<<dp[n][k] <<endl;
}

 

举报

相关推荐

0 条评论