洛谷p1090:优先队列
思路:贪心的每次合并最小的两个堆
代码:
# include <bits/stdc++.h>
using namespace std;
priority_queue<long , vector<long>, greater<long>>q;
int main ()
{
int n,x;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
q.push(x);
}
long ans=0;
while(q.size()>=2)
{
int a,b;
a=q.top();
q.pop();
b=q.top();
q.pop();
long sum=a+b;
ans+=sum;
q.push(sum);
}
printf("%d",ans);
return 0;
}
p3817:贪心
思路:贪心策略:对于相邻两个数每次考虑第二个数,使得每次考虑中,所需要减少的糖果更少
代码:
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll read()
{
ll k;
scanf("%lld",&k);
return k;
}
ll a[20005];
int main ()
{
ll n,x;
n=read(),x=read();
for(ll i=1;i<=n;i++)
{
a[i]=read();
}
ll ans=0;
for(ll i=2;i<=n;i++)
{
if(a[i]+a[i-1]>x)
{
ans+=(a[i]+a[i-1]-x);
a[i]=x-a[i-1];
}
}
printf("%lld",ans);
return 0;
}
洛谷p1106:贪心
思路:贪心策略:每次删除前一个比后一个大的数,注意:删完一个数后下次又要从第0位开始
代码:
#include <bits/stdc++.h>
using namespace std;
int main ()
{
int k;
string s;
cin>>s>>k;
int sum=s.length(),len;
len=sum;
while(len>sum-k)
{
for(int i=0;i<=len;i++)
{
while(s[0]=='0')
{s.erase(0,1);}//去除前导0,之所以不消耗删除次数是因为我们不会输出前面有0的整数;
if(s[i]>s[i+1])
{
s.erase(i,1);
len--;
break;
}
}
//Q:如果把最后一个0给删了,就会错误,但并未错,为什么?
//A:程序是先删前导0在删数,如果只剩下0了,就说明已经删完了。
//即输出至少都是0,当只剩下0时就代表删除完成
}
for(int i=0;i<sum-k;i++)cout<<s[i];
return 0;
}