寻找最大值
#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);
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 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.采用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++;
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();
}
页:
[1]