天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 40|回复: 0

寻找最大值

[复制链接]
  • TA的每日心情
    开心
    昨天 08:49
  • 签到天数: 79 天

    [LV.6]常住居民II

    1543

    主题

    198

    回帖

    214748万

    积分

    管理员

    积分
    2147483647
    发表于 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. }
    复制代码

     

     

     

     

    寻找最大值
    中国膜结构网打造全中国最好的膜结构综合平台 ,统一协调膜结构设计,膜结构施工,膜材采购,膜材定制,膜结构预算全方位服务。 中国空间膜结构协会合作单位。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|中国膜结构网_中国空间膜结构协会

    GMT+8, 2024-5-13 09:49 , Processed in 0.060357 second(s), 21 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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