假设我有号码x
,号码列表和最大号码y
。我需要找到最大结果,我可以通过将x
添加到列表中每个元素的加法或减法中来获得最大结果,使得求和不超过y
且不低于0.
注意:您必须在列表中添加或减去每个元素,这意味着您不能跳过数字。
示例:
x= 3 y=10 list={2,6,1}
我可以得到:3 - 2 + 6 +1 = 8
小于10且小于0
失败案例为3+2+6+1= 12
,即>因此无效的解决方案。
另一个失败案例 3-2-6 = -5
(此处不需要在6之后检查元素,因为你的号码被拒绝了)
如何找到这个最大值?
答案 0 :(得分:3)
因此,您基本上有一个列表l
和一个y-x
号码(如果您必须添加x
,并获得y
,则很容易看到它是相当于获取y-x
)并且您希望在l
中添加/减去每个元素并尽可能接近值y-x
。
请注意,问题等同于Partition Problem NP-Complete,因为如果您有一个列表l
,并且值y-x == 0
- 则需要找到两个子列表l1,l2
,使sum(l1) - sum(l2) == 0
和l1 union l2 = l
正好是分区问题。
因此 - 没有已知的多项式解决方案。
我会看一下指数(例如回溯)解决方案,或pseudo polynomial DP solution for the related subset sum problem的变体。
答案 1 :(得分:0)
以下是解决方案:
int x = 3, y = 10;
var lst = new List<int>{ 1, 2, 3, 4 };
int n = (int)Math.Pow(2, lst.Count);
var lst2 = new List<List<int>>();
for (int i = 0; i < n; i++)
{
var lstCopy = new int[lst.Count];
lst.CopyTo(lstCopy);
for (int j = 1; j <= i; j *= 2)
if ((j & i) != 0)
lstCopy[(int)Math.Log(j, 2)] *= -1;
lst2.Add(lstCopy.ToList());
}
bool yes = lst2.Select(l=>x + l.Sum()).Any(l=>l > 0 && l < y);
if (yes)
Console.WriteLine(lst2.Select(l => x + l.Sum()).Where(l => l > 0 && l < y).First());
请注意,您需要检查2 ^ n个整数数组,其中n是原始数组的长度(它是您的{2,6,1}}