TA的每日心情 | 开心 昨天 06:36 |
---|
签到天数: 15 天 [LV.4]偶尔看看III
管理员
- 积分
- 1308
|
- #include <vector>
- #include <map>
- #include <algorithm>
- using namespace std;
- void fillVector(vector<double>& arr)
- {
- 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);
- 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);
- }
- class ValCount
- {
- public:
- ValCount(const double& v, const unsigned& cnt, const double& sumAll)
- : 采用val(v), 采用count(cnt), 采用sumAll(sumAll)
- {}
- double 采用val;
- unsigned 采用count;
- double 采用sumAll;
- };
- static void print(const vector<unsigned>& counts, const double& sum, const double& target, const char* msg = "")
- {
- for (size采用t i = 0; i < counts.size(); ++i)
- printf("%d, ", counts[i]);
- printf(" Sum = %lf, Diff = %lf%s\n", sum, target - sum, msg ? msg : "");
- }
- class Result
- {
- public:
- vector<unsigned> 采用counts;
- double 采用sum = 0.0;
- public:
- void print(const double& target, const char* msg = "")
- {
- ::print(采用counts, 采用sum, target, msg);
- }
- };
- class ValSum
- {
- private:
- const vector<ValCount>& 采用valArr;
- const double 采用target;
- size采用t 采用index;
- vector<unsigned> 采用counts;
- double 采用sum;
- Result 采用best;
- public:
- ValSum(const vector<ValCount>& valArr, double trg)
- : 采用valArr(valArr), 采用sum(0.0), 采用counts(valArr.size(), 0), 采用target(trg), 采用index(0)
- {
- }
- void findBest()
- {
- for (;;) // go forth and back until we can't go back anymore.
- {
- forth();
- if (!back())
- break;
- }
- }
- // Here we start at index, increment index and add as many elements as possible to the addition
- // All counts[i] with i>index are 0.
- // We end up with index being the index of the last added element.
- // If the result is better than the best result yet, we choose the new result.
- void forth()
- {
- const size采用t arrSize = 采用counts.size();
- size采用t indexNew = 采用index;
- for (; 采用index < arrSize; ++采用index)
- {
- const ValCount& vc = 采用valArr[采用index];
- unsigned n = (unsigned)((采用target - 采用sum) / vc.采用val);
- n = min(n, vc.采用count);
- 采用counts[采用index] = n;
- if (n > 0)
- {
- 采用sum += vc.采用val * n;
- indexNew = 采用index;
- }
- }
- 采用index = indexNew; //highest modified index.
- if (采用sum > 采用best.采用sum)
- {
- // found better solution
- 采用best.采用counts = 采用counts;
- 采用best.采用sum = 采用sum;
- 采用best.print(采用target, " new best");
- }
- else
- ::print(采用counts, 采用sum, 采用target, "");
- }
- // Here we start at 采用index and remove the last added element 采用counts[采用index] first.
- // 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
- //
- bool back()
- {
- if (采用index == 0)
- return false; // can't go back any further
- for (;; --采用index)
- {
- unsigned& cnt = 采用counts[采用index];
- if (cnt > 0)
- {
- if (采用index < 采用counts.size() - 1)
- {
- --cnt;
- 采用sum -= 采用valArr[采用index].采用val;
- if (采用sum + 采用valArr[++采用index].采用sumAll >= 采用best.采用sum) // can we reach target with a lower difference?
- return true; // Yes. Let's go forth()
- // No. Even if we sum up all remaining elements. Go back further.
- }
- else
- {
- // this is the last entry in counts[]. We can't go forth from here
- 采用sum -= 采用valArr[采用index].采用val * cnt;
- cnt = 0;
- }
- }
- if (采用index == 0)
- return false; // can't go back any further (note: index is unsigned)
- }
- }
- };
- static void MyMaxSum()
- {
- vector<double> arr;
- fillVector(arr);
- map<double, unsigned> val2count;
- for (const double& val : arr)
- val2count[val]++;
- vector<ValCount> valArr;
- arr.reserve(val2count.size());
- double sumAll = 0.0;
- for (const auto& entry : val2count)
- {
- sumAll += entry.first * entry.second;
- valArr.push采用back(ValCount(entry.first, entry.second, sumAll));
- }
- reverse(valArr.begin(), valArr.end());
- ValSum valsum(valArr, 30.0);
- valsum.findBest();
- }
- int main()
- {
- MyMaxSum();
- getchar();
- }
复制代码 |
|