【发布时间】:2012-05-15 17:12:07
【问题描述】:
我最近遇到了以下面试问题,我想知道动态编程方法是否可行,或者/和是否有某种数学洞察力可以使解决方案更容易......它与 ieee754 如何加倍非常相似被构造出来。
问题: 有 N 个双精度值的向量 V。其中向量的第 i 个索引处的值等于 1/2^(i+1)。例如:1/2、1/4、1/8、1/16 等...
您将编写一个函数,该函数将一个双倍 'r' 作为输入,其中 0
此外,索引的数量应该最少,如果有两个解决方案,应该首选最接近零的解决方案。
void getIndexes(std::vector<double>& V, double r)
{
....
}
int main()
{
std::vector<double> V;
// populate V...
double r = 0.3;
getIndexes(V,r);
return 0;
}
注意:似乎有一些 SO'ers 没有完全阅读问题的心情。所以让大家注意以下几点:
解决方案,也就是总和可能大于 r - 因此,任何从 r 中递增减去分数,直到它达到零或接近零的策略都是错误的
有r的例子,这里会有2个解,即|r-s0| == |r-s1|并且 s0
如果您认为这个问题是微不足道的,那么您很可能还没有理解它。因此,最好再次阅读该问题。
编辑(Matthieu M.):V = {1/2, 1/4, 1/8, 1/16, 1/32} 的 2 个示例
-
r = 0.3,S = {1, 3} -
r = 0.256652,S = {1}
【问题讨论】:
-
@amit:其实我觉得这是背包问题的简化版。
-
@MatthieuM:为了简单起见,我认为可以忽略双精度误差,基本上可以假设总和是正确的——理论上应该是这样,因为添加了2,这是单比特表示 - 但我离题了:)
-
@XanderTulip:关于您的编辑 - 进一步考虑您是正确的,这个问题可能不承认贪婪的解决方案。如果您在问题中添加具体示例,人们可能会发现这更容易理解(例如,
0.6的最佳表示为分数的总和。){进一步说明:您可能不是故意的,但您的评论“似乎有些 SO'ers 没有心情完全阅读这个问题......”听起来有点刺耳。纠正误解很好,但要礼貌。} -
给我看一个 V 和 r 的例子以及解集。
-
一个例子是将
0.70表示为集合{0.500, 0.250, 0.125}中数字的总和。贪心算法(如我删除的答案)给出0.500 + 0.125 = 0.625,其错误为0.075。更好的解决方案是0.500 + 0.250 = 0.750,错误为0.050。
标签: c++ algorithm dynamic-programming