【发布时间】:2014-09-22 14:13:28
【问题描述】:
给定一个n 数字列表和s 的总和,将这些数字分组到two 组中,使得每组中的数字总和为less than or equal to s。如果可以分组,打印YES,如果不能分组,打印NO。
例如,如果n=3 , s=4 和n 数字是2,4,2。
在这种情况下,输出为YES,因为可以形成两个组是(2,2) and (4)。
我的解决方案如下。
A 是包含 n 个数字的整数数组。
first group 包含第一组元素的总和。
second group 包含第二组元素的总和。
解决方案 1
- 按降序对数组进行排序。
- 继续向第二组添加数字,直到该组中元素的总和小于或等于
s。 - 将第一组的总和计算为
sum of all elements减去sum of elements in second group -
如果每组元素的总和小于或等于
s,则打印YES,否则打印NO。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
使用Greedy approach
- 按降序对数组进行排序。
- 将数组中的第一个元素添加到第一组。
- 遍历其余元素并将每个元素添加到总和最小的组中。
-
如果两个组的元素之和等于
sum_of_all_elements,则打印YES,否则打印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";
问题
上面提到的两种解决方案都给出了错误的答案。我不明白他们在哪些情况下失败了。
如果有人可以帮助我解决此问题的任何其他替代解决方案,那就太好了。
【问题讨论】: