欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 将数组和减半的最少操作次数(贪心)

将数组和减半的最少操作次数(贪心)

2025/5/14 23:05:00 来源:https://blog.csdn.net/Fy10030629/article/details/147571349  浏览:    关键词:将数组和减半的最少操作次数(贪心)

  • 问题描述
  • 解题思路
  • 算法实现
  • 正确性证明

问题描述

给你一个正整数数组 nums 。每一次操作中,你可以从 nums 中选择 任意 一个数并将它减小到 恰好 一半。(注意,在后续操作中你可以对减半过的数继续执行操作)
请你返回将 nums 数组和 至少 减少一半的 最少 操作数。

解题思路

采取贪心策略来解决这个问题。那么什么情况下是局部最优解呢?
很显然,一次操作中,将数组中最大数减半是使得数组之和减少最多的。换言之,这就是我们所求的局部最优解。
那么明确了贪心策略之后,我们的算法就是通过对数组最大值不断减半来实现。

算法实现

class Solution {
public:int halveArray(vector<int>& nums){priority_queue<double>heap;int count = 0;double mins = 0, sum = 0;for (auto& e : nums){heap.push(e);sum += e;}while (mins < sum/2){double t = heap.top();heap.pop();t /= 2;mins += t;count++;heap.push(t);}return count;}
};
int main()
{vector<double>arr(10);double sum = 0, ans = 0;for (int i = 0; i < 10; i++){cin >> arr[i];sum += arr[i];}sum /= 10;for (int i = 0; i < 10; i++){ans += (arr[i] - sum) * (arr[i] - sum);}cout << sum << endl<< ans / 9 << endl;return 0;
}

正确性证明

这里依旧采用交换论证法。
对于最优策略a1,a2,…,an,贪心策略b1,b2,…,bn。
考虑两种策略前k-1项相同,第k项不同。此时存在两种情况:
1.不存在am=bk,m>k。则考虑将ak转换成bk,由于bk操作使得数组减少量大于ak操作,即保证了正确性不发生改变。
2.存在am=bk,m>k。交换am和ak,但由于存在al,k<l<m使用的是原ak减半后的操作数。故需要将al与am交换,若重复出现该情况则继续交换。不难发现单纯的操作顺序变换不会使得正确性发生变化。

重复上述操作使得最优策略a1,a2,…,an转换为贪心策略b1,b2,…,bn。
即正确性得证。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词