给定一个< code>n数和sum s
的列表,将这些数分成< code >两个组,使得每组中的数之和小于或等于s。如果可以分组,则打印< code>YES,如果不能分组,则打印< code>NO。
例如,如果< code>n=3,s=4和< code>n数是< code>2,4,2。在这种情况下,输出为< code>YES,因为可以形成两个组< code>(2,2)和(4)。
我的解决方案如下。
A
是包含n个数字的整数数组。
第一组
包含第一组元素的总和。
第二组
包含第二组中的元素之和。
解决方案 1
>
s
如果每组元素的总和小于或等于s,则打印
是
,否则打印否
。
qsort (A, n, sizeof(int),compare);
int second_group=0;
f=0;
for(i=0;i<n;++i)
{
if((second_group+A[i])==s)
{
f=1;
break;
}
else if((second_group+A[i])<s)
{
second_group+=A[i];
}
}
int first_group=sum_of_all_elements-second_group;
if(f==1)
{
cout<<"YES\n";
}
else if ((second_group<=s) && (first_group<=s))
{
cout<<"YES\n";
}
else
{
cout<<"NO\n";
}
解决方案2 使用
贪婪的方法
> < li >按降序对数组进行排序。
< li >将数组中的第一个元素添加到第一组。 < li >迭代其余元素,并将每个元素添加到具有最小总和的组中。 < li>
如果两组元素的总和等于< code>sum_of_all_elements
,则打印< code>YES,否则打印< code>NO。
qsort (A, n, sizeof(int),compare);
int first_group=0,second_group=0;
f=0;
first_group=A[0];
for(i=1;i<n;++i)
{
if(first_group<second_group)
{
if((first_group+A[i])<=s)
first_group+=A[i];
}
else
{
if((second_group+A[i])<=s)
second_group+=A[i];
}
}
if((first_group+second_group)==sum_of_all_elements)
cout<<"YES\n";
else
cout<<"NO\n";
问题
上面提到的两种解决方案都给出了不正确的答案。我无法理解他们失败的场景。
如果有人能帮助我解决这个问题的任何其他替代解决方案,那就太好了。
快速尝试-A的总和必须是
你能给更多的测试用例吗?或者只是一个我的algh不起作用的案例。
你假设所有最小的元素都在一个组里,这不一定正确。
以下面的例子为例:
array = {1, 2, 4, 6} , s = 7
对于上述情况,您的两种解决方案都会产生错误的输出。
让我先澄清一下你想解决什么问题。你正试图解决子集和问题的一个修改版本。让我换个方式问你:
1. Give an array A and a sum S. Find the subset of A with the largest sum S1
such that S1 <= S. (We want the largest sum because it will give the
smallest possible sum for the rest of the elements).
2. Now the sum of the rest of the elements is S2 = TotalSum - S1. If S2 <= S,
print YES otherwise print NO.
子集和问题是一个NP难问题,不能在多项式时间内求解。然而,该问题存在一个基于动态规划的伪多项式时间算法。参见子集和问题或动态规划:子集和的伪多项式解。这个想法是这样的:
Use dynamic programming to calculate whether there is a solution to the
subset sum problem for sum = S. If there is a solution, then report YES
if TotalSum - S <= S. Otherwise pick the largest sum that exists in the
DP table (just select the last row with subset sum = True entry in the
last column). Let this sum be S1.
If S1 <= S report YES otherwise NO.
通过在构造DP时记住额外的信息,您还可以记住导致您为第一个子集选择的和S1的子集。
我有以下情况: > 具有两个表的Android sqlite数据库: 表1--1:N--2 表1 表2 int id(PK) 接下来,我将介绍以下Android java结构: 因此,我需要根据如下条件将数据从数据库选择到atable1 arraylist: 问题是,必须根据表2中的字段t1\u id(table2.t1\u id=table1.id)选择arraylist atable1中的ar
问题内容: 假设列表中没有连续的整数。 我已经尝试过使用NumPy()来解决每个元素之间的差异,但是还无法使用它来获得答案。下面是输入(第一行)和预期输出(第二行)的两个示例。 问题答案: 您可以用来对列表中的顺序元素对启用迭代,并跟踪序列未增加的索引值,以便将相应的切片附加到输出列表中。
问题内容: 我正在寻找一种将python列表轻松分成两半的方法。 这样,如果我有一个数组: 我将能够得到: 问题答案: 如果需要功能:
问题内容: 我有一个清单: 如何将带有动态间隙的最近值分组,并创建这样的元组,最快的方法是什么?: 问题答案: 喜欢 首先,我们计算顺序元素之间的平均差异,然后将差异小于平均值的元素分组在一起。
问题内容: 我定义 当我尝试通过以下方式将其转换为数组时: 我得到这个异常: 为什么?它与Integer到Integer完全相同。当类是父子关系时,这不是一般情况 我尝试进行投射: 但是在这里我得到这个错误: 问题是什么? 问题答案: 由于类型擦除,ArrayList在运行时不知道其通用类型,因此它只能为您提供最通用的Object []。您需要使用另一个toArray方法,该方法允许您指定所需的数
问题内容: 在Java中将列表拆分为两个子列表的最简单,最标准和/或最有效的方法是什么?可以更改原始列表,因此无需复制。方法签名可以是 [EDIT] 返回原始列表上的视图,如果修改了原始视图,该视图将无效。因此,除非它也放弃了原始参考文献,否则无法使用(或者,如Marc Novakowski的回答所述,使用但立即复制结果)。 问题答案: 快速半伪代码: 它使用标准的List实现方法,并避免了所有循