目录
一,贪心算法例题:
本节只进行贪心算法的引入,即介绍一下贪心的思想:
寻找最优解,并付诸实践。
题目一:
这道题只用明白,每一个人,只能 最多达到第二高的默契值。
#include<iostream>
#include<algorithm>
using namespace std;
int an[501][501],n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) {
for(int j=i+1;j<=n;j++) {
cin>>an[i][j];
an[j][i]=an[i][j];
}
}
int ans = 0;
for(int i=1;i<=n;i++)
{
sort(an[i],an[i]+n+1);
if(an[i][n-1] > ans)
ans = an[i][n-1];
}
cout<<1<<endl<<ans;
return 0;
}
题目二:
这道题可以联想相同质量两物体进行完全弹性碰撞。
#include<iostream>
using namespace std;
int main(){
int len,a[5005],n;
cin>>len>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
int max=0;
int min=0;
for(int i=0;i<n;i++){
if(a[i]>max) max=a[i];
if(len+1-a[i]>max) max=len+1-a[i];
}
for(int i=0;i<n;i++){
if(a[i]<len+1-a[i]){
if(a[i]>min) {
min=a[i];
}
}
else if(a[i]>=len+1-a[i]){
if(len+1-a[i]>min)
min=len+1-a[i];
}
}
cout<<min<<" "<<max;
return 0;
}
题目三:
注意应该将用时少的往前放,尽量不占用大家时间。
#include<bits/stdc++.h>
using namespace std;
int n,a[1010]={0,},b[1010];
double t1,t2;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[i]=a[i];
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
t1+=a[i-1];
t2+=t1;
for(int j=1;j<=n;j++)
{
if(a[i]==b[j])
{
cout<<j<<" ";
b[j]=0;
}
}
}
t2/=n;
cout<<endl<<fixed<<setprecision(2)<<t2;
return 0;
}
题目四:
这道题只需将两个最小的果子放一起(使用优先队列),最后就是正确答案。
如果必须紧挨着合并,那就需要运用动态规划的知识了。
#include<iostream>
#include<utility>
#include<queue>
using namespace std;
int n,x,ans;
priority_queue<int,vector<int>,greater<int> >q;
//使用优先队列
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>x,q.push(x);
while(q.size()>=2){
int firsttop=q.top(); q.pop();
int secondtop=q.top(); q.pop();
ans=ans+secondtop+firsttop;
q.push(firsttop+secondtop);
}
cout<<ans<<endl;
return 0;
}
以上四题是贪心思想的简单引入,并未使用过多算法, 仅仅在最后一个使用了一个优先队列----小顶堆。
二,优先队列:
1.优先队列引入:
首先明确优先队列定义:priority_queue<Type, Container, Functional>,显然包含三个部分:Type 数据类型,Container 容器类型,Functional 比较的方式。
例如:
//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> > q;
(注意最后两个右箭头不能紧挨着,会导致错判为位移符)
后两个部分可以选择不写,只保留数据类型,此时默认按大顶堆走(最大的数在最顶端,从大到小),看如下一个例子:
#include<bits/stdc++.h>
using namespace std;
int main()
{
priority_queue<int> first;
priority_queue<int, vector<int>, greater<int> > second;
priority_queue<string> third;
for (int i = 0; i < 3; i++)
{
first.push(i);
second.push(i);
}
while (!first.empty())
{
cout << first.top() << ' ';
first.pop();
}
cout << endl;
while (!second.empty())
{
cout << second.top() << ' ';
second.pop();
}
cout << endl;
third.push("ab");
third.push("ac");
third.push("bd");
while (!third.empty())
{
cout << third.top() << ' ';
third.pop();
}
cout << endl;
return 0;
}
输出结果:
2 1 0
0 1 2
cd ac ab
其中出现了区别大小顶堆的方法,即改变第三个参数,使用less与greater来区分大小顶堆。
2.常规使用:
push() | 将新元素插入 |
pop() | 将优先级最高的元素从队列中删除 |
top() | 寻址优先队列的最顶层元素 |
size() | 返回优先队列的大小 |
empty() | 验证队列是否为空,空返回false(0),非空返回true(1) |
swap() | 将优先队列的元素与具有相同类型和大小的另一个队列交换 |
emplace() | 在优先队列的顶部插入一个新元素 |
3.使用中特殊情况:
pari的比较,先比较第一个元素,第一个相等比较第二个,如下例:
#include<bits/stdc++.h>
using namespace std;
int main()
{
priority_queue<pair<int, int>,vector<pair<int,int> >,greater<pair<int,int> > > fir;
pair<int, int> sec(1, 2);
pair<int, int> thi(1, 3);
pair<int, int> for(2, 5);
fir.push(sec);
fir.push(thi);
fir.push(for);
while (!fir.empty())
{
cout << fir.top().first << ' ' << fir.top().second << '\n';
fir.pop();
}
}
输出:
1 2
1 3
2 5