简单贪心
Problem:
P2240
将金币单价从高到低排序
P1803
将结束时间从早到晚排序
举个例子:
1.一个比赛被另一个比赛包含
----
--------
选择比赛1,因为结束早,这样后续比赛被占用的时间可能较少
2.一个比赛和另一个比赛相交
--------
----
选择比赛1,同理。
P1223
数学手法,写过题解,不再赘述
P1090
合并最小的两个,优先级队列(从小到大)
priority_queue<int,vector<int>,greater<int> >q;
P3817
特殊处理第一个,因为要最小,把它吃到只剩x个就行了,然后照例处理依次往后
P1106
看高位是否大于低位,即前一个是否大于后一个,注意前导0
P1478
读进来时,只要x<=a+b,这一组数据入队好了,想要摘到最多苹果,那么y要尽量小,所以将y从小到大排序就好了。
P5019&P3078&P1969(三题同解)
如果a[i]>a[i-1] ans+=a[i]-a[i-1] 。填平一个坑的同时,旁边的坑也会被填上一点,如果旁边是个较大的坑,那么会剩下a[i]-a[i-1]
Code:
P2240
#include <bits/stdc++.h>
using namespace std;
struct coin
{
int m;
int v;
}a[105];
int n,t;
inline bool cmp(coin a,coin b)
{
return a.v*b.m>a.m*b.v;//a.v/a.m>b.v/b.m 避开浮点小数
}
int main()
{
cin>>n>>t;
for(int i=1;i<=n;i++)
cin>>a[i].m>>a[i].v;
sort(a+1,a+n+1,cmp);
int cnt;
float ans=0;
for(cnt=1;cnt<=n;cnt++)
{
if(a[cnt].m>t) break;
ans+=a[cnt].v;
t-=a[cnt].m;
}
if(cnt<n)
ans+=1.0*t/a[cnt].m*a[cnt].v;
cout<<fixed<<setprecision(2)<<ans;
return 0;
}
P1803
#include<bits/stdc++.h>
using namespace std;
struct oj
{
int s;
int e;
}a[1000005];
int n;
int finish,ans;
inline bool cmp(oj a,oj b)
{
return a.e<b.e;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i].s>>a[i].e;
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(finish<=a[i].s)
{
ans++;
finish=a[i].e;
}
}
cout<<ans<<endl;
return 0;
}
P1090
#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;
}
P3817
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
ll a[100005];
ll ans,x;
int main()
{
cin>>n>>x;
cin>>a[1];
if(a[1]>x)
{
ans+=a[1]-x;
a[1]=x;
}
for(int i=2;i<=n;i++)
{
cin>>a[i];
if(a[i]+a[i-1]>x)
{
ans+=a[i]+a[i-1]-x;
a[i]=x-a[i-1];
}
}
cout<<ans;
return 0;
}
P1106
#include <bits/stdc++.h>
using namespace std;
string s;
int n,a[251];
int main()
{
cin>>s;
cin>>n;
int len=s.size();
for(int i=0;i<len;i++)
a[i]=s[i]-'0';
for(int k=1;k<=n;k++)//删去个数
{
for(int i=0;i<len;i++)//整体扫描
{
if(a[i]>a[i+1])//找到一个低位大于高位
{
for(int j=i;j<len;j++)//向前移一位
a[j]=a[j+1];
len--;//长度--
break;//跳出来,寻找下一个
}
}
}
int i=0;
while(a[i]==0 && i<len-1) i++;//前导0
for(int j=i;j<len;j++) cout<<a[j];
return 0;
}
P1478
#include <bits/stdc++.h>
using namespace std;
int n,a,b,s,can,ans;
int tx,ty;
struct apple
{
int xi;
int yi;
}ap[5005];
bool cmp(apple a,apple b)
{
return a.yi<b.yi;
}
int main()
{
cin>>n>>s;
cin>>a>>b;
for(int i=1;i<=n;i++)
{
cin>>tx>>ty;
if(tx<=a+b)
{
can++;
ap[can].xi=tx;
ap[can].yi=ty;
}
}
sort(ap+1,ap+can+1,cmp);
for(int i=1;i<=can&&s>=ap[i].yi;i++)
{
ans++;
s-=ap[i].yi;
}
cout<<ans<<endl;
return 0;
}
P3078
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,a,last;
ll ans;
int main()
{
cin>>n;
for(ll i=1;i<=n;i++)
{
cin>>a;
if(a>last) ans+=a-last;
last=a;
}
cout<<ans<<endl;
return 0;
}
曾几何时,我也开始刷水题了,还自得其乐