贪心算法
贪心算法
贪心,就是只考虑当前状态,每一次选择最优的方案.
什么时候贪心是正确的?
当当前状态对后面状态无影响或者后面状态依赖于当前状态时贪心可用.
这东西还是要具体问题具体分析.
例题:合并果子
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆. 多多决定把所有的果子合成一堆.
每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和. 可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了. 多多在合并果子时总共消耗的体力等于每次合并所耗体力之和.
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力. 假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值.
例如有3种果子,数目依次为1,2,9. 可以先将1、2堆合并,新堆数目为3,耗费体力为3. 接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12. 所以多多总共耗费体力=3+12=15. 可以证明15为最小的体力耗费值.
贪心选择最小的体力耗费情况,然后模拟即可.
点击查看代码
#include<bits/stdc++.h>
#define ll int
#define rg register
#define rll rg ll
#define maxn 20001
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
rll f=0,x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10|'0'); }
ll n,t,cnt,ans,p=1,num1=1,num2=1;
ll a[maxn],b[maxn];
int main()
{
memset(a,0x3f,sizeof(a));memset(b,0x3f,sizeof(b));
n=read();for(rll i=1;i<=n;i++) a[i]=read();sort(a+1,a+n+1);
while(p<n)
{
for(rll i=1;i<=2;i++) if(a[num1]<b[num2]) t+=a[num1++]; else t+=b[num2++];
p++;ans+=(b[++cnt]=t);t=0;
}
write(ans);
return 0;
}
优先队列
优先队列(也叫堆),是一个 STL 容器,可以将内部元素按照顺序排序.
实现:
priority_queue<类型名> q;
这样默认是大根堆,也可以使用小根堆:
priority_queue<类型名,vector<类型名>,greater<类型名> > q;
要自定义比较函数,直接覆盖上面 greater 位置的内容即可.
--END--

浙公网安备 33010602011771号
我的博客: 𝟷𝙻𝚒𝚞
本文链接: https://www.cnblogs.com/1Liu/articles/16755746.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!