贪心
知识点
局部最优解->整体最优解
贪心算法理论基础!_哔哩哔哩_bilibili
选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
证明贪心策略的有效性
· 反证法
· 数学归纳法
例题
376.摆动序列
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.size() <= 1) return nums.size();
int curDiff = 0; // 当前⼀对差值
int preDiff = 0; // 前⼀对差值
int result = 1; // 记录峰值个数,序列默认序列最右边有⼀个峰值
for (int i = 0; i < nums.size() - 1; i++) {
curDiff = nums[i + 1] - nums[i];
// 出现峰值
if ((curDiff > 0 && preDiff <= 0) || (preDiff >= 0 &&
curDiff < 0)) {
result++;
preDiff = curDiff;
}
}
return result;
}};
P1090 [NOIP2004 提高组] 合并果子
[NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G - 洛谷
补充知识:优先队列
定义:
priority_queue<int>q;
从小到大:
priority_queue<int,vector<int>,greater<int> >q;
如果你想从大到小的话可以重载运算符:
struct Node{
int x,y;
Node(int a=0, int b=0):
x(a), y(b) {}
};
struct cmp{
bool operator()(Node a, Node b){
if(a.x == b.x) return a.y>b.y;
return a.x>b.x;
}
};
priority_queue<Node,vector<Node>,cmp>q;
或者你也可以用less
priority_queue<int,vector<int>,less<int> >q;
题解:
#include<bits/stdc++.h>
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 a=q.top(); q.pop();
int b=q.top(); q.pop();
ans+=a+b;
q.push(a+b);
}
cout<<ans<<endl;
return 0;
}
二分查找和二分答案
【算法1-6】二分查找与二分答案 - 题单 - 洛谷
二分查找
int Search(int num,int low,int high)
{
int mid;
while(low<=high)
{
mid=(low+high)/2;
if(num>=b[mid]) low=mid+1;
else high=mid-1;
}
return low;
}
二分答案
使用二分答案技巧的条件:
1)命题可以被归纳为找到使得某命题P(x)成立(或不成立)的最大(或最小)的x
2)把P(x)看作一个值真或假的函数,那么它一定在某个分界线的一侧全为真,另一侧全为假
3)可以找到一个复杂度优秀的算法来检测P(x)的真假
通俗来讲,二分答案可以用来处理“最大的最小”或“最小的最大”问题
模板:
最大值最小化
while(l<r)
{
int mid=(l+r)>>1;
if(check(mid))
{
r=mid;
}
else
{
l=mid+1;
}
}
最小值最大化
while(l<r)
{
int mid=(l+r+1)>>1;//注意这里是l+r+1
if(check(mid))
{
l=mid;
}
else
{
r=mid-1;
}
}
小数二分模版
while(r-l>eps)//eps为精度
{
int mid=(l+r)>>1;
if(check(mid))
{
r=mid;
}
else
{
l=mid;
}
}
判断可行性
//这里已经得到l
if(ok(l))
{
yes;
}
else
{
no;
}
例题
P1102 A-B 数对
A-B 数对 - 洛谷
这题绝了 好多种优秀的做法(映射 二分 hash 桶 )
Aggressive cows(c语言)_克里斯蒂亚诺.CR7的博客-CSDN博客
先二分距离 然后放牛判断可不可以
Multiplication Table_Apollo-yyy的博客-CSDN博客
lower_bound() upper_bound()
c++的lower_bound函数、upper_bound和find函数_无敌少年小旋风的博客-CSDN博客
三分法
左右三分之一点
取最大值为例->设小区间