【发布时间】:2018-08-05 07:06:50
【问题描述】:
我如何运行快速动态规划算法来获得所有可能的答案。 假设我们有 20 个条目,它只显示 1 行最佳答案,我希望它一直运行并显示其他条目,直到所有条目都显示出来,并且不允许重复。 太感谢了。真的很感激。 这是代码:
#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <utility>
using namespace std;
float W ,N; //N = olcu sayisi, W = profil boyu
vector<float> numbers; //stores the set of numbers
pair<float, multiset<float>> calc(float i, float j) //returns closest sum and best subset of the first i numbers for the target value j
{
static map<pair<float, float>, pair<float, multiset<float>>> dp; //stores results to avoid repeated calculations
pair<float, float> p(i, j); //pair for convenience
if(i == 0) //base case
{
return make_pair(0, multiset<float>(
{}));
}
auto findResult = dp.find(p);
if(findResult != dp.end()) //check if already calculated
{
return findResult->second;
}
auto temp1 = calc(i - 1, j); //compute result if not using number
if(numbers[i - 1] > j) //if current number is too big
{
return temp1;
}
auto temp2 = calc(i - 1, j - numbers[i - 1]); //compute result if using number
temp2.first += numbers[i - 1];
temp2.second.insert(numbers[i - 1]);
pair<float, multiset<float>> result;
if(temp1.first != temp2.first) //compare results and choose best
{
result = temp1.first > temp2.first ? temp1 : temp2;
}
else
{
result = temp1.second.size() < temp2.second.size() ? temp1 : temp2;
}
dp[p] = result;
return result;
}
int main()
{
cout << "sineklik sayisi: ";
cin >> N;
N = 2 * N;
cout << "Profil olcusu: ";
cin >> W;
numbers.reserve(N); //avoid extra reallocations
cout << "Olculeri giriniz: ";
for(int i = 0; i < N; i++) //input loop
{
float temp;
cin >> temp;
numbers.push_back(temp);
}
pair<float, multiset<float>> result = calc(N, W); //calculate
//output below
cout << "The best possible sum is " << result.first << " Left behind is " << W - result.first << ", obtained using the set of numbers {";
if(result.second.size() > 0)
{
cout << *result.second.begin();
for(auto i = ++result.second.begin(); i != result.second.end(); i++)
{
cout << ", " << *i;
}
}
cout << "}.\n";
}
【问题讨论】:
-
所有可能的答案都是一个非常棘手的问题。道格拉斯·亚当斯(Douglas Adams)为此工作了很长时间,他能做到的最好成绩是 42 岁
-
那么我们必须取下一个最好的,显示最好的条目总和就可以了,但我们必须显示所有条目,不要重复,例如:条目:10,20,30, 40,50,60 目标总和 : 70 答案 : {10,60},{50,20},{30,40} ----- 现在它只显示 {10,60} 以供回答真诚感谢各位跨度>
-
@user4581301 你能帮帮我吗?欣赏它。
-
我正在研究它,不需要其他问题。如果不阅读代码,大多数人甚至都不知道您在说什么。
-
@FeiXiang 非常感谢你,我知道我可以依靠你,衷心感谢。
标签: c++ optimization mathematical-optimization