「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」。
这是一个贪心算法的题目。贪心算法的思想和动态规划的算法思想不同,动态规划的思想是将问题化成一个个子问题,但是这些子问题之间是有联系的。而贪心算法是观察当前问题的状态的一个最优选择,做完这个选择后,问题进入新的状态,再选择这个新状态最优选择,这样一步步做下去,直到解决问题。
题目
给定n堆石子,每次操作使两堆石子合并在一起,一次合并的得分是两堆石子所含石子的乘积,到最后只剩一堆石子时结束,求最大的得分。
思路
我们用贪心的思想来解这道题目,怎么来使最终得分和最多。我们第一次合并的时候就让这次合并是所有情况合并中是最多的分,这一次合并后。下一次合并还是按照上一次合并的要求,我们最终就能得出最大的得分。那我们如何在程序中做到每次合并都能得最多分呢?这个很简单,我们只需选择当前石子中石子数最多的两堆石子就可以了。具体做法就是,用vector容器存储石子堆,每次合并后都要删除一个石子堆,直到最后只剩一个石子堆得出答案。在开始操作前,我们还需要对这些石子堆进行排序,从大到小进行排序,这样之后操作才能得出正确的答案。
代码
#include<bits/stdc++.h>
using namespace std;
long long sum=0;
bool cmp(int a,int b){
if(a>b)
reture true;
return false;
}
int main(){
int n;
cin>>n;
vector<long long> a(n);//确定石子堆的数目
for(int i=0;i<n;i++){
cin>>a[i];
}
while(a.size()>1){
sort(a.begin(),a.end(),cmp);
// sort(a.begin(),a.end(),greater<int>());//这种方法也可以降序排序
sum+=(a[0]+1)*(a[1]+1);
a[1]=a[0]+a[1];
a.erase(a.begin());//每次都删掉第一个数,两个数的和都存储在第二个数上
}
cout<<sum<<endl;
return 0;
}