给定N个整数。这些数字中的每一个都可以增加或减少一次不超过给定的正整数L.在每次操作之后,如果任何数字变得相等,我们将它们视为一个数字。问题是计算最小不同整数集的基数。
约束:N <= 100,L <= 3200,整数在[-32000,32000]范围内
示例:N = 3,L = 10 11 21 27
1)将11增加10 =&gt; 21 21 27
2)减少27乘以6 =&gt; 21 21 21
答案是1。
Algo in C ++ language:
sort(v.begin(), v.end());
// the algo tries to include elements in interval of length 2 * L
int ans = 0;
int first = 0;
for(int i = 1; i < N; ++i) {
if(v[i] - v[first] > 2 * L) { // if we can't include i-th element
ans++; // into the current interval
first = i; // the algo construct new
}
}
ans++;
printf("%d", ans);
我试着理解为什么这个贪婪的算法是最佳的。任何帮助表示赞赏。
答案 0 :(得分:2)
重新设计,我们试图尽可能少地基数2*L + 1
覆盖输入中出现的数字集。您可以想象,对于时间间隔[C - L, C + L]
,其中的所有数字都会调整为C
。
根据排序顺序给出任何间隔列表,我们可以在k
中进行归纳显示,仅考虑第一个k
间隔,贪婪的第一个k
至少覆盖了k = 0
输入。基本案例class FirstCustomSegue: UIStoryboardSegue {
override func perform() {
// Assign the source and destination views to local variables.
var firstVCView = self.sourceViewController.view as UIView!
var secondVCView = self.destinationViewController.view as UIView!
// Get the screen width and height.
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
// Specify the initial position of the destination view.
secondVCView.frame = CGRectMake(screenWidth, 0.0, screenWidth, screenHeight)
// Access the app's key window and insert the destination view above the current (source) one.
let window = UIApplication.sharedApplication().keyWindow
window?.insertSubview(secondVCView, aboveSubview: firstVCView)
// Animate the transition.
UIView.animateWithDuration(0.4, animations: { () -> Void in
firstVCView.frame = CGRectOffset(firstVCView.frame, -screenWidth, -0.0)
secondVCView.frame = CGRectOffset(secondVCView.frame, -screenWidth, -0.0)
}) { (Finished) -> Void in
self.sourceViewController.presentViewController(self.destinationViewController as! UIViewController,
animated: false,
completion: nil)
}
}
}
是微不足道的。感性地,贪婪覆盖下一个未被覆盖的输入元素,并且尽可能多地覆盖它;覆盖其下一个未覆盖的输入元素的任意解决方案中的间隔必须不在贪婪之后,因此任意解决方案不再具有覆盖范围。