首页 > 其他分享 >n的m划分

n的m划分

时间:2024-05-13 11:09:14浏览次数:15  
标签:... 数列 int 划分 允许 dp

一、问题描述

有 \(n\) 个相同的物品,将它们划分成 \(m\) 组,有几种划分方法。

注:以下划分都算一种:

1 + 1 + 2
1 + 2 + 1
2 + 1 + 1

二、问题简析

本题采用动态规划求解。令 \(dp[i][j]=\) \(i\) 的 \(j\) 划分的方案数。值得注意的是,本题根据是否可以有 \(0\) 存在,即允许某一组的值为 \(0\),分成两种情况。

允许 \(0\) 存在
设数列 \(\{a_n\}\) 为 \(dp[i][j]\) 的方案,则 \(\sum_{n=1}^ja_n=i\)。
数列 \(\{a_n\}\) 存在两种情况:

  • 没有 \(0\),即 \(a_n>0\)。
    如何得到这个数列呢?我们可以对数列 \(\{a_n-1\}\) 的每个元素 +1。数列 \(\{a_n-1\}\) 的元素和 \(\sum_{n=1}^j=i-j\),即 \(dp[i-j][j]\) 的方案。
  • 存在 \(0\)
    我们将这个 \(0\) 从数列中分离出来,数列的元素个数变成了 \(j-1\),然而元素之和仍然为 \(i\)。现在的数列是 \(dp[i][j-1]\) 的方案。

综上所述,\(dp[i][j]=dp[i-j][j]+dp[i][j-1]\)。

边界条件:

  • 条件一:\(0\) 允许存在,所以 \(0\) 的任意划分(大于 \(0\))都为 \(1\)。\(dp[0][j]\) 为 \(j\) 个 \(0\)。

\[dp[0][1,2,...]=1 \]

  • 条件二:任意数(包含 \(0\))的 \(1\) 划分都是自身。

\[dp[0,1,...][1]=1 \]

注:此时,\(dp[0][1]=1\)

不允许 \(0\) 存在
设数列 \(\{a_n\}\) 为 \(dp[i][j]\) 的方案,则 \(\sum_{n=1}^ja_n=i\)。
有两种情况对 \(dp[i][j]\) 有贡献:

  • 在 \(dp[i-j][j]\) 的方案基础上,每个元素 +1,就得到了不含 \(0\) 的 \(dp[i][j]\)。这就是上文提到的情况一。
  • 在 \(dp[i-1][j-1]\) 的方案基础上,加入元素 \(1\)。与上文情况二唯一不同的地方就是,此处添加元素 \(1\),上文添加元素 \(0\)。

综上所述,\(dp[i][j]=dp[i-j][j]+dp[i-1][j-1]\)。

边界条件:

  • 条件一:\(0\) 不允许存在,所以 \(0\) 的任意划分(大于 \(0\))都为 \(0\)。

\[dp[0][1,2,...]=0 \]

  • 条件二:任意数(不包含 \(0\))的 \(1\) 划分都是自身。

\[dp[1,2,...][1]=1 \]

注:此时,\(dp[0][1]=0\)

三、例题

P1025 [NOIP2001 提高组] 数的划分

3.1 本题代码

本题不允许 \(0\) 存在。

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int n, k;
ll dp[205][10]; // dp[i][j] -- i的j划分 

int main()
{
	#ifdef LOCAL
	freopen("test.in", "r", stdin);
	#endif
	
	cin >> n >> k;
	
	// 边界条件一:dp[0][1,2,...]=0
	// ...                             // 不允许0存在,所以0的所有划分都为0 
	
	// 边界条件二:dp[1,2,...][1]=1 
	for (int i = 1; i <= n; ++i)       // i的1划分,即自身 
		dp[i][1] = 1;
	
	for (int i = 1; i <= n; ++i)       // i=0已经在条件一中初始化 
	{
		for (int j = 2; j <= k; ++j)   // j=1已经在条件二中初始化 
		{
			if (i >= j)
				dp[i][j] = dp[i - j][j] + dp[i - 1][j - 1];
			// if i < j, dp[i][j] = 0 (因为不能有0存在)
		}
	}
	
	cout << dp[n][k] << endl;
	
	return 0;
}

3.2 改题目:允许 \(0\) 存在

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int n, k;
ll dp[202][10]; 

int main()
{
	#ifdef LOCAL
	freopen("test.in", "r", stdin);
	#endif
	
	cin >> n >> k;
	
	// 边界条件一:允许0存在,任意划分都为1 
	for (int j = 1; j <= k; ++j)
		dp[0][j] = 1;
	// 边界条件二:i的1划分就是自身 
	for (int i = 0; i <= n; ++i)
		dp[i][1] = 1;
		
	for (int i = 1; i <= n; ++i)        // i=0在条件一中初始化 
	{
		for (int j = 2; j <= k; ++j)    // j=1在条件二中初始化 
		{
			if (i >= j)
				dp[i][j] = dp[i - j][j] + dp[i][j - 1];
			else // i<j时,在i个1的基础上,添j-i个0 
				dp[i][j] = 1;
		}
	}
	
	cout << dp[n][k] << endl;
	
	return 0;
}

标签:...,数列,int,划分,允许,dp
From: https://www.cnblogs.com/hoyd/p/18188822

相关文章

  • 763. 划分字母区间
    给你一个字符串s。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是s。返回一个表示每个字符串片段的长度的列表。示例1:输入:s="ababcbacadefegdehijhklij"输出:[9,7,8]解释:划......
  • 1-ICEM入门练习:正方体网格划分(六面体网格)
    1.前言采用简单几何结构进行网格划分,主要目的是熟悉ICEM操作流程及网格划分思路,参考B站博主视频进行自己练习。基本操作:鼠标中键--平移、ctrl+鼠标左键--旋转、鼠标右键上下滑动--放大缩小2.几何结构采用spceclaim建模20mm×20mm×20mm正方体几何,无需定义边界,保存文件类型......
  • 微服务划分的原则
    服务划分服务的合理划分是微服务成功的重中之重,是所有项目实施之前必须认真思考,严肃对待的。那么怎样划分才算是合理呢?以业务、技术、团队导向规划服务我们必须明确的是:服务不是越细越好,服务划分的第一要素是先以业务域水平拆分,再以技术视角垂直拆分,结合团队的规模、能力确定服......
  • 蓝桥杯-数的划分(DFS)
    0.题目问题描述将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。例如:n=7,k=3,下面三种分法被认为是相同的。1,1,5;1,5,1;5,1,1;问有多少种不同的分法。输入格式n,k输出格式一个整数,即不同的分法样例输入73样例输出4数据......
  • 36天【代码随想录算法训练营34期】第八章 贪心算法 part05( ● 435. 无重叠区间 ● 7
    435.无重叠区间classSolution:deferaseOverlapIntervals(self,intervals:List[List[int]])->int:count=0intervals.sort(key=lambdax:x[0])foriinrange(1,len(intervals)):ifintervals[i][0]<intervals[i-......
  • [IOI2019] 景点划分
    令人忍俊不禁的是,11月的模拟赛出现了“摩拉克斯”一题,被取之。2月JOISC出现这个模型,被取之。2月模拟赛出现这个模型,被取之。本题再次出现这个模型,被取之。呃呃呃呃呃呃呃呃呃啊。首先进行一些简单的分析:令\(A\leB\leC\),构造\(A,B\)合法的情况即可。并且有\(A\len/......
  • 07、VXLAN网关划分
    VXLAN网关划分和VLAN类似,不同VNI之间的VXLAN,及VXLAN和非VXLAN之间不能直接相互通信。为了使VXLAN之间,以及VXLAN和非VXLAN之间能够进行通信,VXLAN引入了VXLAN网关。VXLAN网关分为:二层网关:用于解决租户接入VXLAN虚拟网络的问题,也可用于同一VXLAN虚拟网络的子网通信。三层网......
  • mtk相机冷启动阶段划分
     如上图:s0:手指抬起到app创建的时间s1:app创建完成到下发opencamera的时间s2:hal接受到app打开相机消息,connectdevice,给sensor上电,并回调告诉app硬件已经连接成功了s3:app接受到hal的回调之后,认为hal已经准备好了,就创建会话准备进行图像上传s4:hal接受到app已经创......
  • 字节面试:领域、子域、核心域、通用域和支撑域怎么划分?
    领域驱动设计(DDD)里面有一堆专业术语,比如领域、子域、核心域、通用域、支撑域等等,听着是不是觉得挺吓人?别怕,我来带你轻松搞懂它们。如何理解领域和子域?领域是指一定的业务范围或问题域。在解决业务问题时,DDD会将业务领域进行细分,将问题范围限定在一定的边界内,在这个边界内建立领......
  • 【二分+容斥】【ST表/单调栈】【划分型DP】
    二分+容斥题目链接https://leetcode.cn/problems/kth-smallest-amount-with-single-denomination-combination/description/题目大意题目思路假设有一个x元硬币思考只有一种面额为3的硬币时,3可以组成不超过x的面额的数量有x/3种!思考有两种面额【3,6】,可以组成不......