当前位置:   article > 正文

huawei od机试 等和子数组最小和_华为od 等和子数组最小和

华为od 等和子数组最小和

698. 划分为k个相等的子集 - 力扣(LeetCode)   和这道题基本是相同的,就是多了一个循环,从大到小除,就可以找到最小和

leetcode 698. 划分为k个相等的子集-CSDN博客

  1. //huafenzuixiaoxiangdengziji.cpp
  2. //https://zhuanlan.zhihu.com/p/643824546
  3. //https://leetcode.cn/problems/partition-to-k-equal-sum-subsets/solutions/2479339/698-hua-fen-wei-kge-xiang-deng-de-zi-ji-hd44o/
  4. #include<iostream>
  5. #include<vector>
  6. #include<algorithm>
  7. using namespace std;
  8. bool compare(int &a, int &c) {
  9. return a > c;
  10. }
  11. bool recursion(int sum, vector<int>& nums, int start, int len, int target, vector<bool>& status, int k) {
  12. if(k==1) return true; //最后还剩下一个数组需要找,但是默认不需要找了 allsum - (k-1)*target = target,直接返回的呢
  13. if(sum==target) return recursion(0, nums, 0, len, target, status, k-1); // 满足条件的,找到了一个子数组,剩下要找的子数组数量减一:k-1
  14. int tmpsum=0;
  15. // 不在循环内做判断,判断交给了上面的sum==target,循环内只做剪枝和加和
  16. // 循环内只累加一个数字,剩下可能的累加交给了其他递归
  17. for(int i = start; i < len; i++) { // 每个递归的循环都只处理一个 数字的加和,剩下的交给其他递归处理
  18. if(status[i]==true) continue; // 剪枝,这个数字已经标记true,累加过了的
  19. tmpsum = sum + nums[i]; //累加
  20. if(tmpsum > target) { // 剪枝,累加和>target,可以直接跳过
  21. continue;
  22. }
  23. status[i] = true; //和这个数字相加,状态置true
  24. if(recursion(tmpsum, nums, i+1, len, target, status, k)) return true; // 交给其他递归处理,和剩下的数字相加,起始点 i+1
  25. // 返回了false,也就是不满足条件,不能和这个数字相加,回溯的false
  26. status[i] = false;
  27. while(i+1 < len && nums[i+1]==nums[i]) { // 既然不能和这个数字相加,那么剩下的相等的数字就可以直接跳过,剪枝
  28. i++;
  29. }
  30. }
  31. return false; // 都尝试累加过了,剩下的数字没有符合条件的,返回false。
  32. }
  33. class Solution {
  34. public:
  35. bool canPartitionKSubsets(vector<int>& nums, int k, int target) {
  36. for(int i = 0; i < nums.size(); i++) {
  37. if(nums[i] > target) {
  38. return false;
  39. }
  40. }
  41. vector<bool> status(nums.size(), false);
  42. bool ret = recursion(0, nums, 0, nums.size(), target, status, k);
  43. return ret;
  44. }
  45. };
  46. int main(void) {
  47. int i, j, k, m, n, x, y, z, sum = 0;
  48. // k = 2*2;
  49. // int a[] = {4, 3, 2, 3, 5, 2, 1};
  50. // k = 3;
  51. // int a[] = {1, 2, 3, 4};
  52. int a[] = {4,3,2,3,5,2,1};
  53. int len = sizeof(a) / sizeof(*a);
  54. vector<int> arr(len);
  55. for(i = 0; i < len; i++) {
  56. arr[i] = a[i];
  57. }
  58. // for(i = 0; i < k; i++) scanf("%d", &arr[i]);
  59. sort(arr.begin(), arr.end(), compare);
  60. for(i = 0; i < arr.size(); i++) {
  61. sum += arr[i];
  62. }
  63. Solution ltt = Solution();
  64. bool ret;
  65. for(k = len; k >= 1; k--) {
  66. if(sum%k!=0) {
  67. continue;
  68. }
  69. ret = ltt.canPartitionKSubsets(arr, k, sum / k);
  70. if(ret) {
  71. cout<<sum / k<<endl;
  72. return 0;
  73. }
  74. }
  75. cout<<"false"<<endl;
  76. return 0;
  77. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/444511
推荐阅读
相关标签
  

闽ICP备14008679号