题目描述:

Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.

Note:

  1. Each of the array element will not exceed 100.
  2. The array size will not exceed 200.

示例:

Input: [1, 5, 11, 5]Output: trueExplanation: The array can be partitioned as [1, 5, 5] and [11].思路:一个背包的题目,背包容量为数组中元素和的一半+1,这样只要看是否有元素可以正好填满背包即可.但是每个元素只能用一次,所以在尝试放一个元素的时候还要避免他对尝试放其他位置时对自己的影响.所以在尝试放一个元素到背包的时候需要从容量最大的位置开始,如果(当前位置-当前元素大小)位置可以通过放置之前的元素达到,则当前位置也可以通过放置当前元素正好达到这个位置.状态转移方程为:dp[i] = dp[i] || dp[i - nums[k]];代码如下所示,但是该算法中的dp是啥?
  1. class Solution {
  2. public:
  3. bool canPartition(vector<int>& nums) {
  4. int sum = accumulate(nums.begin(), nums.end(), 0);
  5. if(sum&1) return false;
  6. vector<int> dp(sum/2+1, 0);
  7. for(int i = 0, dp[0] = 1; i < nums.size(); i++)
  8. {
  9. for(int j = sum/2; j >= nums[i]; j--)
  10. dp[j] = dp[j] || dp[j-nums[i]];
  11. }
  12. return dp[sum/2];
  13. }
  14. }; 提交在leetcode上面,编译没通过。

查看另外一个人的博客,发现解释的更为仔细,具体如下:

这道题给了我们一个数组,问我们这个数组能不能分成两个非空子集合,使得两个子集合的元素之和相同。那么我们想,原数组所有数字和一定是偶数,不然根本无法拆成两个和相同的子集合,那么我们只需要算出原数组的数字之和,然后除以2,就是我们的target,那么问题就转换为能不能找到一个非空子集合,使得其数字之和为target。开始我想的是遍历所有子集合,算和,但是这种方法无法通过OJ的大数据集合。于是乎,动态规划DP就是我们的不二之选。我们定义一个一维的dp数组,其中dp[i]表示数字i是否是原数组的任意个子集合之和,那么我们我们最后只需要返回dp[target]就行了。我们初始化dp[0]为true,由于题目中限制了所有数字为正数,那么我们就不用担心会出现和为0或者负数的情况。那么关键问题就是要找出递归公式了,我们需要遍历原数组中的数字,对于遍历到的每个数字nums[i],我们需要更新我们的dp数组,要更新[nums[i], target]之间的值,那么对于这个区间中的任意一个数字j,如果dp[j - nums[j]]为true的话,那么dp[j]就一定为true,于是地推公式如下:

dp[j] = dp[j] || dp[j - nums[i]]         (nums[i] <= j <= target)   但是某个dp[x]为真,在程序中我们要如何表示呢,这点我还是不会。

class Solution {
public:bool canPartition(vector<int>& nums) { int sum = accumulate(nums.begin(), nums.end(), 0); if (sum % 2 == 1) return false; int target = sum / 2; vector<bool> dp(target + 1, false); dp[0] = true; for (int i = 0; i < nums.size(); ++i) { for (int j = target; j >= nums[i]; --j) { dp[j] = dp[j] || dp[j - nums[i]]; } } return dp.back(); } };

手动计算了一遍程序,我感觉很多地方没太看懂。具体问题如下:1.首先动态规划问题应该是由小算到大。由前面的值推算出后面的值,但是代码中的第二层for循环,却是先算的大(而且这个大还不知道怎么计算。。。)2.dp的定义没看懂,dp.back()这个函数是什么也不知道。

转载于:https://www.cnblogs.com/maowuyu-xb/p/6433271.html

动态规划------平均切分数组之和为两部分相关推荐

  1. 快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值

    我觉得写得很清晰,希望没有侵犯作者的著作权,原文地址http://blog.csdn.net/hackbuteer1/article/details/6699642 快速找出一个数组中的两个数字,让这 ...

  2. leetcode算法题--K 次串联后最大子数组之和★

    原题链接:https://leetcode-cn.com/problems/k-concatenation-maximum-sum/ 如图(来源) 记k==1,数组和为sum 分情况讨论: 当k == ...

  3. LeetCode 01两数之和02两数相加

    力扣 LeetCode01两数之和 LeetCode02两数之加 前言:第一次LeetCode打卡题解,前面组织的打卡活动从今天开始正式开始了,很多csdn和公众号小伙伴以及加入了,欢迎加入!详细看力 ...

  4. mysql 两个数相加_LeetCode 01两数之和02两数相加

    LeetCode01两数之和 题目描述:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案 ...

  5. 环形数组求最大子数组之和

    环形数组求最大子数组之和: 实验要求: 随机产生一个整形数组,假设首尾相连为环形,求其相连的字数组的和,并输出子数组的元素. 设计思路: 因为是环形,所以要考虑自设的头尾的情况,在此分为两大类考虑,一 ...

  6. 我理解的算法 - 三数之和及两数、三数之和扩展题

    我理解的算法 - 三数之和及两数.三数之和扩展题 LeetCode 15.三数之和 扩展 三数之和变种题 两数之和变种题 LeetCode 15.三数之和 这道题的题目大家自行查看:链接在这 ,题目和 ...

  7. 力扣198.打家劫舍---动态规划与滚动数组

    力扣198.打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动 ...

  8. 在一个数组中实现两个堆栈

    本题要求在一个数组中实现两个堆栈. 函数接口定义: Stack CreateStack( int MaxSize ); bool Push( Stack S, ElementType X,int Ta ...

  9. 求数组最大数,该数为数组中某两个数相加

    题目: 百度笔试:在一个正整数集合S中,找出一个最大数C,使得C=A+B,其中A和B也是S种的元素. 思想: 首先,我们将数组从小到大进行快速排序.其次: 1.将最后一个数设为最大数设定为S: 2.用 ...

  10. c#数据结构之集合的实现(数组及链表两种实现)

    集合的概念 集合是由一些确定的.彼此不同的成员或者元素构成的一个整体.如果将紧密相关的数据组合到一个集合中,则能够更有效地处理这些紧密相关的数据.代替编写不同的代码来处理每一单独的对象,您可以使用相同 ...

最新文章

  1. LeetCode简单题之三维形体的表面积
  2. 第二篇:n-gram 语言模型
  3. 三菱modbusRTU通讯实例_干货 | 解析西门子系列PLC编程实例
  4. Hologres揭秘:深度解析高效率分布式查询引擎
  5. linux dhcpd 设置 关于 subnet
  6. hcna华为认证网络工程师
  7. 界面控件DotNetBar for WinForms使用教程:highlight组件使用教程
  8. android 蓝牙打印乱码,蓝牙打印机打印中文乱码
  9. springboot毕设项目热贡文化艺术展示与定制s5g19(java+VUE+Mybatis+Maven+Mysql)
  10. python自动获取北京时间_python将当前服务器的时区时间转为北京时间
  11. Python数模笔记-NetworkX(5)关键路径法
  12. “有点笨”的数学大师迈克尔·弗里德曼
  13. android 涂鸦软件demo,涂鸦demo(swift)这是一款涂鸦软件,能够实现对图片的基本操作...
  14. 点,线,面,透视(手绘课)
  15. 中国移动手机话费查询号码1008611
  16. 程序员如何写出技术好文?
  17. 爱否赢了?华为拍月亮方法已申请专利
  18. 菜鸟win7双系统安装教程 两个系统都用Win7
  19. 全局钩子+正则表达式=后台自动获取扫描枪数据
  20. 第一节云计算课程的感想

热门文章

  1. Jersey客户端API调用REST风格的Web服务
  2. Oracle DB_LINK如何使用
  3. C#表驱动法+一点反射实现“得到指定位数随机不重复字符串”三种方式的封装...
  4. CLRS2e读书笔记—Chapter10
  5. oracle中控制字段不为null
  6. GridView中的超级链接
  7. 机器学习基础:期望最大化算法(Machine Learning Fundamentals: EM Algorithm)
  8. 机器学习基础:支持向量机(Machine Learning Fundamentals: Support Vector Machine, SVM)
  9. 【Flutter】Dart的数据类型listMap(数组和字典)
  10. 如何使用EasyRecovery的监控硬盘功能