2021-07-26

洛谷“水题”U147020 喵星出征

一道完美 的贪心+01背包的题目(完美就怪了
U147020 喵星出征

题目描述
众所周知,猫的故乡是遥远的星球“喵星”,他们来到地球为了奴役无知人类。成功入侵地球后,喵始皇有了征服世界的打算,他派出自己的得力侦察员去收集这个世界的情报:具体而言,除“喵星”外,宇宙中还有n颗星球。每个星球都有自己的势力值,当“喵星”的势力值p大于星球i的势力值ai时,喵星人就可以征服并吞并它,并获得bi的势力值。这个bi可能是正的(军队扩充,文化繁荣等情况),也有可能是负的(政治内乱,资源匮乏等情况)。喵始皇想尽可能多地去征服其它星球,他要求征战的过程中“喵星”势力值p必须始终大于0。请计算他最多能征服多少颗星球。

注意!注意!注意!

p一定要大于0!

p一定要大于0!

p一定要大于0!

重要的事情说三遍

输入格式
输入由n+1行构成。
第1行两个用单个空格隔开的整数n,p,分别代表除“喵星”外的星球个数及“喵星”初始的势力值。
第2行到第n+1行,每行两个用单个空格隔开的整数ai和bi ,其中第i+1行的两个数代表第i个星球的势力值以及被征服后“喵星”势力值的增长值。
输出格式
仅一行一个整数,表示喵始皇最多可以征服的星球个数。

此处无提醒

输入输出样例1
输入
3 5
4 1
5 1
6 1
输出
3
输入输出样例2
输入
6 3
5 -9
1 3
3 -3
3 -5
3 5
1 1
输出
5

依旧无提醒(就是玩儿)

说明/提示
对于第一个样例,喵星人可以按照1号星球→2号星球→3号星球的顺序吞并至多3颗星球。
对于第二个样例,喵星人可以按照按照2号星球→5号星球→6号星球→3号星球→4号星球的顺序吞并至多5颗星球。

有没有发现什么问题?

2号星球→5号星球→6号星球→3号星球→4号星球

啊哈,它没有按照顺序吞并
这说明了这题不可以纯贪心,还需要加亿点点01背包

注意了数据范围n<=300,p<=30000,b<=500;

一定要把数组开大点!!!……(此处省略一亿个“!”)

废话不多说上大佬的思路和代码
ps:不是我的
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
struct Mzccc{
	long long x,y;
};
bool MAX(const Mzccc b,const Mzccc c){
	return b.x<c.x;
}
bool MAX2(const Mzccc b,const Mzccc c){
	return b.y>c.y;
}
long long n,p,e,f,ans=0,ans1=0;
Mzccc a[333],d[333];
int main(){
	cin>>n>>p;
	for(int i=1;i<=n;i++){
		cin>>e>>f;
		if(f>=0)a[i].x=e,a[i].y=f,ans++;
		else d[i].x=e,d[i].y=abs(f),ans1++;
	}
	sort(a+1,a+ans+1,MAX);
	int k=1;
	while(k<=ans&&a[k].x<=p){
		p+=a[k].y;
		k++;
	}
	k--;
	sort(d+1,d+ans1+1,MAX2);
	int j=1,ans2=0;
	while(j<=ans1){
		if(d[j].y<p&&d[j].x<=p)p-=d[j].y,ans2++;
		j++;
	}
	cout<<k+ans2<<endl;
	return 0;
}

最后提交你会发现
在这里插入图片描述
在这里插入图片描述
我怎么说的
在这里插入图片描述
现在,我们再上我的AC代码把

#include<bits/stdc++.h>
using namespace std;
struct Mzccc{
	long long x,y;
};
Mzccc a[333],ans3[333];
long long n,p,ans1=0,ans2=0,f=0,ans4[181111];
bool MAX(const Mzccc b,const Mzccc c){
	return b.x<c.x;
}
int main(){
	cin>>n>>p;
	for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y;	
	sort(a+1,a+n+1,MAX);
	int k=1;
	while(a[k].x<=p&&k<=n){
		if(a[k].y>=0){
			p+=a[k].y;
			a[k].y=INT_MAX;	
			ans2++;
		}
		else{
			ans1++;
			ans3[ans1].x=abs(a[k].y);
			ans3[ans1].y=a[k].x;
		}
		k++;
	}//贪心	
	for(int i=1;i<=ans1;i++){
		for(int j=p;j>=ans3[i].x;j--){
			if(j>ans3[i].y)ans4[j]=max(ans4[j],ans4[j-ans3[i].x]+1);
			f=max(f,ans4[j]);
		}
	}//01背包,注意在减的时候可能出现实力不够,不能征服的情况所以判断一下if(j>ans3[i].y)
	ans2+=f;
	cout<<ans2<<endl;
	return 0;
}

大佬勿喷,谢谢
给个赞再走好不好(求求了
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值