热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HOJ1402:整数分解与组合优化问题研究

HOJ1402题目涉及整数划分的经典问题,旨在通过具体的实例提升对组合数学的理解和应用能力。该问题不仅考察了基本的数学原理,还要求对算法优化有深入的认识,以高效解决大规模数据下的整数分解与组合优化挑战。

HOJ1402 整数划分

http://acm.hit.edu.cn/hoj/problem/view?id=1402

【题目描述】

整数划分是一个经典的问题。希望这道题会对你的组合数学的解题能力有所帮助。

Input

每组输入是两个整数n和k。(1 <&#61; n <&#61; 50, 1 <&#61; k <&#61; n)

Output

对于每组输入&#xff0c;请输出六行。

第一行&#xff1a; 将n划分成若干正整数之和的划分数。
第二行&#xff1a; 将n划分成k个正整数之和的划分数。
第三行&#xff1a; 将n划分成最大数不超过k的划分数。
第四行&#xff1a; 将n划分成若干奇正整数之和的划分数。
第五行&#xff1a; 将n划分成若干不同整数之和的划分数。
第六行&#xff1a; 打印一个空行。

Sample Input

5 2

Sample Output

7
2
3
3
3

Hint:

  1. 将5划分成若干正整数之和的划分为&#xff1a; 5, 4&#43;1, 3&#43;2, 3&#43;1&#43;1, 2&#43;2&#43;1, 2&#43;1&#43;1&#43;1, 1&#43;1&#43;1&#43;1&#43;1
  2. 将5划分成2个正整数之和的划分为&#xff1a; 3&#43;2, 4&#43;1
  3. 将5划分成最大数不超过2的划分为&#xff1a; 1&#43;1&#43;1&#43;1&#43;1, 1&#43;1&#43;1&#43;2, 1&#43;2&#43;2
  4. 将5划分成若干奇正整数之和的划分为&#xff1a; 5, 1&#43;1&#43;3, 1&#43;1&#43;1&#43;1&#43;1
  5. 将5划分成若干不同整数之和的划分为&#xff1a; 5, 1&#43;4, 2&#43;3

 

【算法分析】

  

本题相当于5个小问题&#xff0c;首先来看最容易做的第5个小问题&#xff1a;将n划分成若干不同整数之和的划分数。则是一个典型的背包装物品问题&#xff0c;把问题转化一下&#xff0c;即一个容量为n的背包&#xff0c;重量分别为1n的物品各一个&#xff0c;求用若干物品将背包填满的方案总数。

利用动态规划的思想&#xff0c;很容易得到方程F[I,J] &#61; F[I-1,J] &#43;F[I-1,J-I]&#xff0c;其中F[I,J]表示从前I个物品中用若干个组成的总重量为J的方案总数&#xff0c;转移时要保证F[I-1,J-I]有意义。答案为F[n,n]&#xff0c;时间复杂度为O(n2)

对于前3个小问题可以归结为一个问题&#xff0c;即第2个小问题&#xff1a;把将n划分成k个正整数之和的划分数。

为了避免重复&#xff0c;我们需要按照不下降的顺序进行排列。我们形象地可以把nk份自然数划分看作n块积木堆成k列&#xff0c;那么不妨设这n块积木从左到右被堆成“阶梯状”。比如&#xff0c;下图表示的是3104份自然数划分。

 

而将该图旋转90度&#xff0c;可以很容易想出一种状态表示方法。

 

F[I,J,K]表示把J划分成I份最大为K的划分方案数&#xff0c;则有F[I,J,K] &#61; F[I-1,J-K,L]&#xff0c;其中L &#61; 1..K。时间复杂度为O&#xff08;n2k2&#xff09;。

而如果观察第一个图&#xff0c;我们还可以得到一种状态表示方式。设F[I,J]表示把I划分成J份的划分方案数&#xff0c;则有F[I,J] &#61; F[I-J,K] &#xff0c;其中K &#61; 0..J。时间复杂度为O&#xff08;nk2&#xff09;。

又由于F[I,J]&#61;F[I-J,K]&#xff08;K &#61; 0..J&#xff09;&#61;F[I-J,K]&#xff08;K &#61; 0..J-1&#xff09;&#43;F[I-J,J] &#61; F[I-1,J-1]&#43;F[I-J,J]&#xff0c;这样就把时间复杂度降为O&#xff08;nk&#xff09;。从另外一个角度想&#xff0c;我们在第一个图中“截去底边”&#xff0c;由于存在一个划分方案中含1的情况&#xff0c;我们无法确定在“截去底边”之后要把I-J分为几个数&#xff0c;那么不妨将划分方案中含1的情况单独列出来讨论&#xff0c;直接得到F[I,J] &#61; F[I-1,J-1]&#43;F[I-J,J]

对于第1个小问题的答案是∑F[N,I]&#xff08;I &#61; 1..N&#xff09;&#xff0c;第2个小问题的答案显然是F[N,K]&#xff0c;而第3个小问题的答案则是∑F[N,I]&#xff08;I &#61; 1..K&#xff09;&#xff0c;考虑上面旋转90度之后的图&#xff0c;你会发现&#xff0c;F[N,I]集合中的最高高度均为I&#xff0c;即将n划分成最大数为I的方案数。

最后来看第4个小问题&#xff0c;就是第2个小问题的分奇偶版本&#xff0c;那么设F[I,J]表示把I划分成J个奇数的划分方案数&#xff0c;G[I,J] 表示把I划分成J个偶数的划分方案数。那么还是用“截去底边”的思想&#xff0c;显然有G[I,J] &#61; F[I-J,J]。但F[I,J]却不是直接等于G[I-J,J]&#xff0c;因为这里又存在一个划分方案中含1的情况&#xff0c;同样将划分方案中含1的情况单独列出来讨论&#xff0c;则有F[I,J] &#61; G[I-J,J] &#43; F[I-1,J-1]。最后的答案就是∑F[N,I]&#xff08;I &#61; 1..N&#xff09;&#xff0c;时间复杂度为O(n2)

 

#include
#include

#include
using namespace std;const int maxn &#61; 51;int n,k;
int f[maxn][maxn], g[maxn][maxn];
int f1[maxn][maxn], f2[maxn][maxn];int main () {int i, j;int ans1, ans2, ans3, ans4, ans5;f1[0][0] &#61; 1;for (i &#61; 1; i )for (j &#61; 1; j <&#61; i; j &#43;&#43;)f1[i][j]&#61;f1[i-j][j]&#43;f1[i-1][j-1];f[0][0] &#61; g[0][0] &#61; 1;for (i &#61; 1; i )for (j &#61; 1; j <&#61; i; j &#43;&#43;){g[i][j] &#61; f[i - j][j];f[i][j] &#61; f[i - 1][j - 1] &#43; g[i - j][j];}for (i &#61; 0; i )f2[i][0] &#61; 1;for (i &#61; 1; i )for (j &#61; 1; j ){f2[i][j] &#61; f2[i - 1][j];if (j - i >&#61; 0)f2[i][j] &#43;&#61; f2[i - 1][j - i];}while (scanf ("%d %d", &n, &k) !&#61; EOF){ans1 &#61; ans2 &#61; ans3 &#61; ans4 &#61; ans5 &#61; 0;for (i &#61; 1; i <&#61; n; i &#43;&#43;)ans1 &#43;&#61; f1[n][i];ans2 &#61; f1[n][k];for (i &#61; 1; i <&#61; k; i &#43;&#43;)ans3 &#43;&#61; f1[n][i];for (i &#61; 1; i <&#61; n; i &#43;&#43;)ans4 &#43;&#61; f[n][i];ans5 &#61; f2[n][n];printf ("%d\n%d\n%d\n%d\n%d\n\n", ans1, ans2, ans3, ans4, ans5);}return 0;
}

 



推荐阅读
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • Android 九宫格布局详解及实现:人人网应用示例
    本文深入探讨了人人网Android应用中独特的九宫格布局设计,解析其背后的GridView实现原理,并提供详细的代码示例。这种布局方式不仅美观大方,而且在现代Android应用中较为少见,值得开发者借鉴。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 本文介绍了在Windows环境下使用pydoc工具的方法,并详细解释了如何通过命令行和浏览器查看Python内置函数的文档。此外,还提供了关于raw_input和open函数的具体用法和功能说明。 ... [详细]
  • IneedtofocusTextCellsonebyoneviaabuttonclick.ItriedlistView.ScrollTo.我需要通过点击按钮逐个关注Tex ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 高效提取PDF页面的实用技巧
    在学习和工作中,我们经常需要与他人共享PDF格式的资料。然而,有时只需要分享部分内容,而不仅仅是整个文档。本文将介绍如何使用福昕阅读器领鲜版高效地提取PDF页面,以提高文件传输效率和查阅便捷性。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
author-avatar
8o断情戒爱o8
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有