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

开发笔记:洛谷P1025[NOIP2001提高组]数的划分

篇首语:本文由编程笔记#小编为大家整理,主要介绍了洛谷-----P1025 [NOIP2001 提高组] 数的划分相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了洛谷-----P1025 [NOIP2001 提高组] 数的划分相关的知识,希望对你有一定的参考价值。






在这里插入图片描述
在这里插入图片描述



数的划分题解集合


  • 回溯法思想
  • 自下而上的DFS
  • 动态规划---完全背包思想





回溯法思想

思路:

首先这里不考虑顺序,因此是组合问题

这里要求把整数n分成k份,求共有几种分法?

其实就是给你一个可选数组,数组里面元素按降序大小从1----n排列,要求你从里面选择k个数字,每一个数字可以重复选择,要求这k个数字的和等于n,问存在几种方式?

其实就是下面这道题的翻版问法:

leetcode 39. 组合总和—回溯篇2

还是把问题给树形化,变成对一个多叉树的遍历问题

下面看图:
在这里插入图片描述
显然可以看出递归的结束条件:当前已经选择数字的个数等于k时,或者当前的需要进行划分的数字小于等于0时

这里只有等于0才算一种结果,而小于0不是符合要求的结果,并且我们其实可以把小于0的判断放入循环中,这样就不需要进行递归越界判断

这里还有一个剪枝条件:因为最开始选择的一定是最小的数字,那么如果剩余的数字全选第一个最小的数字都比当前的n要大,那么就可以结束循环了

代码:

#include<iostream>
using namespace std;
#include
class Solution
{
int sum &#61; 0;
public:
int solution(int n, int k)
{
backTrace(n, k, 1);
return sum;
}
void backTrace(int n, int k, int index)
{
if (k &#61;&#61; 0)
{
if(n&#61;&#61;0)
sum&#43;&#43;;
return;
}
for (int i &#61; index; i * k <&#61; n; i&#43;&#43;)
backTrace(n - i, k - 1, i);
}
};
int main()
{
Solution s;
int N &#61; 0, K &#61; 0;
cin >> N >> K;
cout << s.solution(N, K) << endl;
return 0;
}

在这里插入图片描述




自下而上的DFS

跟上面自上而下的递归思路和减枝一样&#xff0c;只不过这里改成了自下而上的递归

#include
using namespace std;
#include
int N &#61; 0, K &#61; 0;
class Solution
{
int sum &#61; 0;
public:
int solution()
{
backTrace(0, 0, 1);
return sum;
}
void backTrace(int n, int k, int index)
{
if (k &#61;&#61;K)
{
if(n&#61;&#61;N)
sum&#43;&#43;;
return;
}
for (int i &#61; index; n&#43;i*(K-k)<&#61;N; i&#43;&#43;)
backTrace(n&#43;i, k&#43;1, i);
}
};
int main()
{
Solution s;
cin >> N >> K;
cout << s.solution() << endl;
return 0;
}

在这里插入图片描述




动态规划—完全背包思想

与本题的动态规划思想一致&#xff1a;
leetcode 322. 零钱兑换----完全背包套路解法详细再探

1.dp数组含义

本题可以转化为从1-----i个物品中任意选择num个物品&#xff0c;每个物品数量无限&#xff0c;可选多次&#xff0c;求刚好装满背包的方案数量&#xff0c;背包的大小为i

那么得到dp[i][j][num]数组含义:考虑前i件物品&#xff0c;凑成总和j并且选择物品件数为num的方案总数

2.推导状态转移方程

注意这里物品的编号i就是物品的大小

如果不选择当前物品放入背包&#xff0c;那么dp[i][j][num]&#61;dp[i-1][j][num]

如果选择当前物品放入背包&#xff0c;那么还需要对当前物品多次选取&#xff0c;累计所有可行方案数量&#xff0c;即

//对每个物品考虑选择多次---当前选择物品i的总容量不能大于当前背包的容量j
//并且当前选择的件数也不能超过限制件数k
for (int g &#61; 0; g * i <&#61; j && g <&#61; k; g&#43;&#43;)
{
dp[i][j][k] &#43;&#61; dp[i - 1][j - g * i][k - g];
}

3.dp数组初始化

显然当我们什么物品都不考虑&#xff0c;并且背包容量为0的时候&#xff0c;为一种方案&#xff0c;即dp[0][0][0]&#61;1;

代码:

#include
using namespace std;
#include
class Solution
{
public:
int solution(int bagSize,int num)
{
//这里物品的个数为bagsize 物品的最大容量也为bagsize
vector<vector<vector<int>>> dp(bagSize&#43;1,vector<vector<int>>(bagSize&#43;1,vector<int>(num&#43;1,0)));
dp[0][0][0] &#61; 1;
for (int i &#61; 1; i <&#61; bagSize; i&#43;&#43;)//物品维度
{
for (int j &#61; 0; j <&#61; bagSize; j&#43;&#43;)//容量维度
{
for (int k &#61; 0; k <&#61; num; k&#43;&#43;)//件数维度
{
//对每个物品考虑选择多次---当前选择物品i的总容量不能大于当前背包的容量j
//并且当前选择的件数也不能超过限制件数k
for (int g &#61; 0; g * i <&#61; j && g <&#61; k; g&#43;&#43;)
{
dp[i][j][k] &#43;&#61; dp[i - 1][j - g * i][k - g];
}
}
}
}
return dp[bagSize][bagSize][num];
}
};
int main()
{
Solution s;
int N &#61; 0, K &#61; 0;
cin >> N >> K;
cout << s.solution(N, K) << endl;
return 0;
}

在这里插入图片描述








推荐阅读
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • IB 物理真题解析:比潜热、理想气体的应用
    本文是对2017年IB物理试卷paper 2中一道涉及比潜热、理想气体和功率的大题进行解析。题目涉及液氧蒸发成氧气的过程,讲解了液氧和氧气分子的结构以及蒸发后分子之间的作用力变化。同时,文章也给出了解题技巧,建议根据得分点的数量来合理分配答题时间。最后,文章提供了答案解析,标注了每个得分点的位置。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 判断数组是否全为0_连续子数组的最大和的解题思路及代码方法一_动态规划
    本文介绍了判断数组是否全为0以及求解连续子数组的最大和的解题思路及代码方法一,即动态规划。通过动态规划的方法,可以找出连续子数组的最大和,具体思路是尽量选择正数的部分,遇到负数则不选择进去,遇到正数则保留并继续考察。本文给出了状态定义和状态转移方程,并提供了具体的代码实现。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
author-avatar
手机用户2602915241
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有