一道经典的整数划分题——分弹珠

news2024/11/28 16:04:08

CSDN 博客:一道经典的整数划分题——分弹珠

一、题目描述

这道题目是一道经典的整数划分问题,要求将 (M) 个弹珠分到 (N) 个盘子中,满足以下条件:

  • 允许盘子为空。
  • 两种分法被认为相同当且仅当分配的弹珠数量相同(不考虑顺序)。

例如,将 (7) 个弹珠分到 (3) 个盘子中的方法数是 (8)。如果不考虑盘子顺序,分法包括:
( 7 , 0 , 0 ) , ( 6 , 1 , 0 ) , ( 5 , 2 , 0 ) , ( 5 , 1 , 1 ) , ( 4 , 3 , 0 ) , ( 4 , 2 , 1 ) , ( 3 , 3 , 1 ) , ( 3 , 2 , 2 ) 。 (7,0,0), (6,1,0), (5,2,0), (5,1,1), (4,3,0), (4,2,1), (3,3,1), (3,2,2)。 (7,0,0),(6,1,0),(5,2,0),(5,1,1),(4,3,0),(4,2,1),(3,3,1),(3,2,2)

二、整数划分题的核心思想

整数划分是组合数学中的经典问题。整数划分问题的核心在于:

  • 如果我们用 P ( m , n ) P(m, n) P(m,n)表示将 m m m个物品分到 n n n个容器中的分法数,那么可以利用递推关系解决问题。
递推公式推导

考虑将 M M M 个弹珠分到 N N N个盘子中:

  1. 如果我们规定 盘子 N N N为空,那么问题就转化为将 M M M个弹珠分到 N − 1 N-1 N1 个盘子中,即 P ( m , n − 1 ) P(m, n-1) P(m,n1)
  2. 如果盘子 N N N 不为空,我们至少需要放一个弹珠,那么问题就转化为将剩下的 M − N M-N MN个弹珠分到 N N N个盘子中,即 P ( m − n , n ) P(m-n, n) P(mn,n)

因此,递推公式为:
P ( m , n ) = P ( m , n − 1 ) + P ( m − n , n ) , P(m, n) = P(m, n-1) + P(m-n, n), P(m,n)=P(m,n1)+P(mn,n),
同时考虑到边界条件:

  • 当 (m = 0) 时,只有一种分法,即所有盘子均为空:
    P ( 0 , n ) = 1 P(0, n) = 1 P(0,n)=1
  • 当 (n = 0) 且 (m > 0) 时,分法数为 (0):
    P ( m , 0 ) = 0 P(m, 0) = 0 P(m,0)=0
  • 当 (n > m) 时,盘子的数量大于弹珠数量,此时最多只需 (m) 个盘子,因此:
    P ( m , n ) = P ( m , m ) P(m, n) = P(m, m) P(m,n)=P(m,m)
三、两种解法详解

方法一:带备忘录的递归

带备忘录的递归利用了记忆化搜索的思想,可以避免重复计算。代码如下:

#include <iostream>
#include <cstring>
using namespace std;

int memo[21][21]; // 备忘录,用于存储中间结果

// 递归计算 P(m, n)
int P(int m, int n) {
    if (m == 0) return 1;          // 边界条件:0个弹珠只有1种分法
    if (m < 0 || n == 0) return 0; // 边界条件:盘子用完或弹珠数量负数
    if (n > m) return P(m, m);     // 若盘子数多于弹珠数,限制盘子数为m

    if (memo[m][n] != -1) return memo[m][n]; // 如果已计算过,直接返回结果

    memo[m][n] = P(m, n-1) + P(m-n, n); // 递推公式
    return memo[m][n];
}

int main() {
    memset(memo, -1, sizeof(memo)); // 初始化备忘录
    int t, M, N;
    while (cin >> t) {
        for (int i = 0; i < t; i++) {
            cin >> M >> N;
            cout << P(M, N) << endl;
        }
    }
    return 0;
}
解法分析
  • 时间复杂度:由于每个状态 P ( m , n ) P(m, n) P(m,n)只计算一次,总的复杂度为 O ( M × N ) O(M \times N) O(M×N)
  • 空间复杂度:需要额外的 O ( M × N ) O(M \times N) O(M×N) 空间存储中间结果。

方法二:分治法(动态规划)

动态规划通过表格存储所有子问题的解,从而避免了递归调用的开销。代码如下:

#include <iostream>
using namespace std;

int dp[21][21]; // 动态规划数组

// 初始化动态规划表
void initialize_dp() {
    for (int m = 0; m <= 20; m++) {
        for (int n = 0; n <= 20; n++) {
            if (m == 0)
                dp[m][n] = 1; // 边界条件
            else if (n == 0)
                dp[m][n] = 0; // 边界条件
            else if (n > m)
                dp[m][n] = dp[m][m]; // 当盘子数多于弹珠数
            else
                dp[m][n] = dp[m][n-1] + dp[m-n][n]; // 递推公式
        }
    }
}

int main() {
    initialize_dp(); // 初始化 DP 表
    int t, M, N;
    while (cin >> t) {
        for (int i = 0; i < t; i++) {
            cin >> M >> N;
            cout << dp[M][N] << endl;
        }
    }
    return 0;
}
解法分析
  • 时间复杂度:预处理的复杂度为 O ( M × N ) O(M \times N) O(M×N),查询的复杂度为 O ( 1 ) O(1) O(1)
  • 空间复杂度:需要 O ( M × N ) O(M \times N) O(M×N) 的存储空间。
四、总结

本题作为整数划分问题的典型代表,考察了递归与动态规划的灵活运用:

  • 递归方法(带备忘录)更容易直观理解,但需要注意栈的深度。
  • 动态规划方法 是实际中更高效且稳定的选择,特别是在多组测试的情况下。

整数划分的核心在于掌握 递推公式 的推导,并灵活运用 边界条件 简化问题的求解。希望本篇博客能够帮助读者对整数划分问题有更深入的理解!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249171.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

应急响应靶机——Windows近源攻击

载入虚拟机&#xff0c;开启虚拟机&#xff0c;点击“解题.exe”&#xff1a; &#xff08;账户密码&#xff1a;Administrator/zgsf2024&#xff09; 1、攻击者的外网IP地址 2、攻击者的内网跳板IP地址 3、攻击者使用的限速软件的md5大写 4、攻击者的后门md5大写 5、攻击…

用两个栈实现队列 剑指offer

题目描述 用两个栈实现一个队列。队列声明如下图&#xff0c;请实现它的两个函数appendTail和deleteHead,分别完成在队尾插入节点和队头删除节点的功能。 代码实现 测试用例 相关题目

超详细ensp配置VRRP和MSTP协议

一、简介 1、什么是VRRP&#xff1a; &#xff08;1&#xff09;VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;的概念&#xff1a; VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;指的是一种实现路由器冗余备份的协议&#xff0c;常用于…

嵌入式Linux开发4——文件类型2

目录 使用stat查明文件类型 stat 命令 stat() 系统调用 struct stat 结构体 常见字段和它们的含义 fstat 函数 示例&#xff1a; lstat 函数 区别总结 使用场景 stat、fstat 和 lstat 比较 链接 硬链接 硬链接的特性 创建硬链接 硬链接的优缺点 符号链接&#…

模电期末笔记 (包过版)

文章目录 一、直流电路公式题型一&#xff1a;电压源与电流源求电压&#xff0c;电流&#xff0c;功率题型二&#xff1a;基尔霍夫定律求电压&#xff0c;电流题型三: 理想电源的等效变换题型四&#xff1a;求复杂电路的电压&#xff0c;电流&#xff0c;电功率**题型五&#x…

C# 常量

文章目录 前言一、整数常量&#xff08;一&#xff09;合法与非法实例对比&#xff08;二&#xff09;不同进制及类型示例 二、浮点常量三、字符常量四、字符串常量五、定义常量 前言 在 C# 编程的世界里&#xff0c;常量是一类特殊的数据元素&#xff0c;它们如同程序中的 “定…

C++11新增的特性

一.列表初始化/{}初始化 回顾&#xff1a;C98中⼀般数组和结构体可以⽤{}进⾏初始化。 1.C11中&#xff0c;一切对象皆可用{}初始化&#xff0c;内置类型⽀持&#xff0c;⾃定义类型也⽀持&#xff08;⾃定义类型本质是类型转换&#xff0c;中间会产⽣临时对象&#xff0c;最…

SAP学习

1、概述 2、SD 2.1 销售中的企业结构 2.2流程概览

Linux之网络基础

网络发展 网络的发展可以从人与人之间的工作模式开始谈起, 人与人的工作模式反应了机器与机器的工作模式: 1. 独立模式: 在网络发展的早期计算机间处于独立模式, 计算机之间相互独立 最开始计算机之间是独立运行的, 数据之间的交互需要人用软盘等存储介质拷贝过去, 一般涉及…

数字图像处理(9):VGA接口及其时序

&#xff08;1&#xff09;特点&#xff1a;成本低、结构简单、应用灵活 VGA接口需要五个信号&#xff1a;R、G、B、Hsync、Vsync &#xff08;2&#xff09;VGA的工作原理&#xff1a; 设定一个高速时钟信号&#xff08;像素时钟&#xff09;来控制每个像素的传输速率&#…

111. UE5 GAS RPG 实现角色技能和场景状态保存到存档

实现角色的技能存档保存和加载 首先&#xff0c;我们在LoadScreenSaveGame.h文件里&#xff0c;增加一个结构体&#xff0c;用于存储技能相关的所有信息 //存储技能的相关信息结构体 USTRUCT(BlueprintType) struct FSavedAbility {GENERATED_BODY()//需要存储的技能UPROPERT…

【jmeter】服务器使用jmeter压力测试(从安装到简单压测示例)

一、服务器上安装jmeter 1、官方下载地址&#xff0c;https://jmeter.apache.org/download_jmeter.cgi 2、服务器上用wget下载 # 更新系统 sudo yum update -y# 安装 wget 以便下载 JMeter sudo yum install wget -y# 下载 JMeter 压缩包&#xff08;使用 JMeter 官方网站的最…

图像算法在生物医药领域的应用

摘要&#xff1a; 随着科技的飞速发展&#xff0c;图像算法在生物医药领域的应用日益广泛且深入。本文详细阐述了图像算法在生物医药多个方面的应用&#xff0c;包括医学影像诊断、病理图像分析、药物研发、细胞图像研究以及生物医学工程等。通过对这些应用的探讨&#xff0c;展…

注意力(Attention)机制详解(附代码)

Attention机制是深度学习中的一种技术&#xff0c;特别是在自然语言处理&#xff08;NLP&#xff09;和计算机视觉领域中得到了广泛的应用。它的核心思想是模仿人类的注意力机制&#xff0c;即人类在处理信息时会集中注意力在某些关键部分上&#xff0c;而忽略其他不那么重要的…

Jmeter测试nginx部署的静态网页最大在线人数

一、下载Jmeter apache-jmeter-5.4.3.tar资源-CSDN文库 解压之后&#xff0c;双击ApacheJMeter.jar,即可打开 二、测试最大在线人数 1、plugins-manager下载安装 起初刚解压的jmeter里面没有插件管理这个选项 去官网下载&#xff1a;Install :: JMeter-Plugins.org 将下载j…

【深度学习|目标跟踪】StrongSort 详解(以及StrongSort++)

StrongSort详解 1、论文及源码2、DeepSort回顾3、StrongSort的EMA4、StrongSort的NSA Kalman5、StrongSort的MC6、StrongSort的BOT特征提取器7、StrongSort的AFLink8、未完待续 1、论文及源码 论文地址&#xff1a;https://arxiv.org/pdf/2202.13514 源码地址&#xff1a;https…

Scala关于成绩的常规操作

score.txt中的数据&#xff1a; 姓名&#xff0c;语文&#xff0c;数学&#xff0c;英语 张伟&#xff0c;87&#xff0c;92&#xff0c;88 李娜&#xff0c;90&#xff0c;85&#xff0c;95 王强&#xff0c;78&#xff0c;90&#xff0c;82 赵敏&#xff0c;92&#xff0c;8…

OpenAI Whisper 语音识别 模型部署及接口封装

环境配置: 一、安装依赖&#xff1a; pip install -U openai-whisper 或者&#xff0c;以下命令会从这个存储库拉取并安装最新的提交&#xff0c;以及其Python依赖项&#xff1a; pip install githttps://github.com/openai/whisper.git 二、安装ffmpeg&#xff1a; cd …

草图大师2020安装教程附安装包下载

软件介绍 草图大师&#xff08;Sketchup&#xff09;是由谷歌公司推出的一款环保型3D建模软件。草图大师可以快速和方便地创建、观察和修改三维创意&#xff0c;具有沿路径放样、导入的2D物体可随视角转动、布尔运算等功能。传统铅笔草图的优雅自如&#xff0c;现代数字科技的…

野火直播 5.7.5x | 频道丰富,有国外频道,部分支持回看

野火直播是一款专为电视盒子设计的电视直播软件&#xff0c;提供海量的电视直播资源和丰富的内容选择。涵盖全球多地的电视台直播源&#xff0c;包括央视、卫视、地方台、海外台等上千个电视频道。软件界面简洁&#xff0c;操作便捷&#xff0c;支持高清流畅播放&#xff0c;并…