找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 164|回复: 0

寻找最大值

[复制链接]

1

主题

0

回帖

35

积分

管理员

积分
35
发表于 2024-4-12 18:10:07 | 显示全部楼层 |阅读模式
  1. #include <vector>
  2. #include <map>
  3. #include <algorithm>
  4. using namespace std;
  5. void fillVector(vector<double>& arr)
  6. {
  7.         arr.push采用back(1.1); arr.push采用back(2.1); arr.push采用back(3.1); arr.push采用back(4.1);; arr.push采用back(5.1);
  8.         arr.push采用back(6.1); arr.push采用back(7.1); arr.push采用back(8.1); arr.push采用back(9.1);; arr.push采用back(10.1);
  9. }
  10. class ValCount
  11. {
  12. public:
  13.         ValCount(const double& v, const unsigned& cnt, const double& sumAll)
  14.                 : 采用val(v), 采用count(cnt), 采用sumAll(sumAll)
  15.         {}
  16.         double   采用val;
  17.         unsigned 采用count;
  18.         double   采用sumAll;
  19. };
  20. static void print(const vector<unsigned>& counts, const double& sum, const double& target, const char* msg = "")
  21. {
  22.         for (size采用t i = 0; i < counts.size(); ++i)
  23.                 printf("%d, ", counts[i]);
  24.         printf("  Sum = %lf, Diff = %lf%s\n", sum, target - sum, msg ? msg : "");
  25. }
  26. class Result
  27. {
  28. public:
  29.         vector<unsigned>        采用counts;
  30.         double                                采用sum = 0.0;
  31. public:
  32.         void print(const double& target, const char* msg = "")
  33.         {
  34.                 ::print(采用counts, 采用sum, target, msg);
  35.         }
  36. };
  37. class ValSum
  38. {
  39. private:
  40.         const vector<ValCount>& 采用valArr;
  41.         const double                    采用target;
  42.         size采用t                                采用index;
  43.         vector<unsigned>        采用counts;
  44.         double                                采用sum;
  45.         Result                                采用best;
  46. public:
  47.         ValSum(const vector<ValCount>& valArr, double trg)
  48.                 : 采用valArr(valArr), 采用sum(0.0), 采用counts(valArr.size(), 0), 采用target(trg), 采用index(0)
  49.         {
  50.         }
  51.         void findBest()
  52.         {
  53.                 for (;;) // go forth and back until we can't go back anymore.
  54.                 {
  55.                         forth();
  56.                         if (!back())
  57.                                 break;
  58.                 }
  59.         }
  60.         // Here we start at index, increment index and add as many elements as possible to the addition
  61.         // All counts[i] with i>index are 0.
  62.         // We end up with index being the index of the last added element.
  63.         // If the result is better than the best result yet, we choose the new result.
  64.         void forth()
  65.         {
  66.                 const size采用t arrSize = 采用counts.size();
  67.                 size采用t indexNew = 采用index;
  68.                 for (; 采用index < arrSize; ++采用index)
  69.                 {
  70.                         const ValCount& vc = 采用valArr[采用index];
  71.                         unsigned n = (unsigned)((采用target - 采用sum) / vc.采用val);
  72.                         n = min(n, vc.采用count);
  73.                         采用counts[采用index] = n;
  74.                         if (n > 0)
  75.                         {
  76.                                 采用sum += vc.采用val * n;
  77.                                 indexNew = 采用index;
  78.                         }
  79.                 }
  80.                 采用index = indexNew; //highest modified index.
  81.                 if (采用sum > 采用best.采用sum)
  82.                 {
  83.                         // found better solution
  84.                         采用best.采用counts = 采用counts;
  85.                         采用best.采用sum = 采用sum;
  86.                         采用best.print(采用target, " new best");
  87.                 }
  88.                 else
  89.                         ::print(采用counts, 采用sum, 采用target, "");
  90.         }
  91.         // Here we start at 采用index and remove the last added element 采用counts[采用index] first.
  92.         // If the sum of all elements 采用valArr[i].采用val with i>采用index is big enough to sum up to target, we go forth with ++采用index
  93.         //
  94.         bool back()
  95.         {
  96.                 if (采用index == 0)
  97.                         return false; // can't go back any further
  98.                 for (;; --采用index)
  99.                 {
  100.                         unsigned& cnt = 采用counts[采用index];
  101.                         if (cnt > 0)
  102.                         {
  103.                                 if (采用index < 采用counts.size() - 1)
  104.                                 {
  105.                                         --cnt;
  106.                                         采用sum -= 采用valArr[采用index].采用val;
  107.                                         if (采用sum + 采用valArr[++采用index].采用sumAll >= 采用best.采用sum) // can we reach target with a lower difference?
  108.                                                 return true; // Yes. Let's go forth()
  109.                                         // No. Even if we sum up all remaining elements. Go back further.
  110.                                 }
  111.                                 else
  112.                                 {
  113.                                         // this is the last entry in counts[]. We can't go forth from here
  114.                                         采用sum -= 采用valArr[采用index].采用val * cnt;
  115.                                         cnt = 0;
  116.                                 }
  117.                         }
  118.                         if (采用index == 0)
  119.                                 return false; // can't go back any further (note: index is unsigned)
  120.                 }
  121.         }
  122. };
  123. static void MyMaxSum()
  124. {
  125.         vector<double> arr;
  126.         fillVector(arr);
  127.         map<double, unsigned> val2count;
  128.         for (const double& val : arr)
  129.                 val2count[val]++;
  130.         vector<ValCount> valArr;
  131.         arr.reserve(val2count.size());
  132.         double sumAll = 0.0;
  133.         for (const auto& entry : val2count)
  134.         {
  135.                 sumAll += entry.first * entry.second;
  136.                 valArr.push采用back(ValCount(entry.first, entry.second, sumAll));
  137.         }
  138.         reverse(valArr.begin(), valArr.end());
  139.         ValSum valsum(valArr, 30.0);
  140.         valsum.findBest();
  141. }
  142. int main()
  143. {
  144.         MyMaxSum();
  145.         getchar();
  146. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2025-1-1 17:19 , Processed in 0.130330 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表