蓝桥杯算法训练22

探讨了将整数n分成k份的不同分法,使用动态规划解决该问题,核心代码展示了如何通过递推公式求解第二类Stirling数。

算法训练 数的划分
时间限制:1.0s 内存限制:256.0MB
问题描述
  将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。
  例如:n=7,k=3,下面三种分法被认为是相同的。
  1,1,5; 1,5,1; 5,1,1;
  问有多少种不同的分法。
输入格式
  n,k
输出格式
  一个整数,即不同的分法
样例输入
7 3
样例输出
4 {四种分法为:1,1,5;1,2,4;1,3,3;2,2,3;}
数据规模和约定
  6<n<=200,2<=k<=6

解题使用动态规划
核心代码:dp[i][j]=dp[i-j][j]+dp[i-1][j-1];
第二类Stirling数的推导和第一类Stirling数类似,可以从定义出发考虑第n+1个元素的情况,假设要把n+1个元素分成m个集合则分析如下:
(1)如果n个元素构成了m-1个集合,那么第n+1个元素单独构成一个集合。方案数 。
(2)如果n个元素已经构成了m个集合,将第n+1个元素插入到任意一个集合。方案数 mS(n,m) 。
综合两种情况得:
S(n+1,m)=S(n,m-1)+m
S(n,m)
例如
(7,3)可以分为(有1的情况):
5 1 1
4 2 1
3 3 1
和(没1的情况):
2 2 3
而7有1的情况就是(6,2)所有情况数量
(6,2)可以分为:
5 1
4 2
3 3
在这两个盒子外加个盒子,这个盒子里放1
还一种情况就是(7-3=4,3)也就是(4,3)的唯一情况:
1 1 2
每个盒子加上1
这两种情况加起来就是最后的结果

最后附上AC源代码:
#include
#include
#define MAXSIZE 201
using namespace std;
int n,k;
int dp[MAXSIZE][MAXSIZE];

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值