贪心算法专题训练 1

贪心专题训练
本周开始在洛谷上刷题了,但是因为最近洛谷不能注册账号了,所以一直和室友用同一个账号,刷的题不多,但是也遇到了一些比较有意思的题。这周主要刷贪心类型的题,顺便复习了sort函数。
1 魔法
Ac代码

#include <iostream>
#include<algorithm>
using namespace std;
const long long int maxn=100000+1;
struct node{
int pre;
int date;
};
bool cmp(node a,node b){
return a.pre+a.date>b.pre+b.date;}
int main()
{
int t;
cin>>t;
while(t--){
  int n,m;
  cin>>n>>m;
  node a[maxn];
for(int i=0;i<n;i++)
cin>>a[i].pre>>a[i].date;
sort(a,a+n,cmp);
int flag=-1;
for(int i=0;i<n;i++)
if(a[i].pre<m){m+=a[i].date;if(m<=0){flag=1;break;}}
else {flag=1;break;}
if(flag==1){
    cout<<"-1s"<<endl;
}else {
cout<<"+1s"<<endl;}
}
}

题目:
cjwssb知道是误会之后,跟你道了歉。你为了逗笑他,准备和他一起开始魔法。不过你的时间不多了,但是更惨的是你还需要完成n个魔法任务。假设你当前的时间为T,每个任务需要有一定的限制ti表示只有当你的T严格大于ti时你才能完成这个任务,完成任务并不需要消耗时间。当你完成第i个任务时,你的时间T会加上bi,此时要保证T在任何时刻都大于0,那么请问你是否能完成这n个魔法任务,如果可以,输出+1s,如果不行,输出-1s。
这道题的精髓在于
bool cmp(node a,node b){
return a.pre+a.date>b.pre+b.date;}
这个排序十分关键。看到题时,很显然能够想到要先算bi大于0的,这样能保证时间足够。一种思路是用两个结构体,一个存bi大于0的,一个存bi小于0的,分类讨论,不过这个方法比较麻烦,没有这个方法简洁。
具体推理过程是:
时间T可能大于大于t1,可是加上b1导致T小于t2,而T加上b2但是大于t1,所以满足方程的公式为
1 T+b1<t2
2 T+b2>t1
3 t1-b2<t2-b1
既 t1+b1<t2+b2
所以应该算t2加b2大的优先,带入特解发现成立。
2 PLES COCI2011-2012#1

#include <iostream>
#include<algorithm>
using namespace std;
const long long int maxn=100000+5;
int a[maxn];
int a1[maxn];
int a2[maxn];
int a3[maxn];
int main()
{
int n;
int s=0;
int s1=0;
int s2=0;
int s3=0;
cin>>n;
for(int i=0;i<n;i++){//a对a3 a1对a2
int k;
cin>>k;
if(k>0){a[s]=k;s++;}
else {a2[s2]=-k;s2++;}
}
for(int i=0;i<n;i++){
int k;
cin>>k;
if(k>0){a1[s1]=k;s1++;}//女
else {a3[s3]=-k;s3++;}
}
int count=0;
sort(a,a+s);
sort(a1,a1+s1);
sort(a2,a2+s2);
sort(a3,a3+s3);
for(int i=0,j=0;i<s&&j<s3;j++)
if(a[i]<a3[j]){i++;count++;}

for(int i=0,j=0;i<s1&&j<s2;j++)
if(a1[i]<a2[j]){i++;count++;}

cout<<count<<endl;

}

题意:
求如果遵照每个人的意愿,最大的舞伴对数是多少。
这道题是很明显的贪心题,但是在做这道题时我总是有很多数据过不了。具体思路是,用4个数组分别存男生大于0和小于0的数以及女生大于0和小于0的数。
但是需要注意一点i和j的顺序。
例如第一个for循环,表示男生必须找比自己高的,两个数组从小到大排序,无论是否成立,那么女生都得选一个更高的,理由是,如果if不成立,那么男生就不能选一个更高的。
总结: 这周主要是刷贪心专题 普及/提高,下周目标也是主要刷贪心专题,以及搜索专题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值