B3872 [GESP202309 五级] 巧夺大奖

题目传送门

前言:怎么说呢,就是一道贪心题,发一遍就过了,然后这不马上就要考CSP-J/S了吗?祝各位OI竞赛者们(当然也包括我自己)RP++,废话不多说进入题解。

题解:

翻译:

这道题给的题目解释有点绕,感觉很含蓄,又很笼统。题目大意:给定了n个任务,要在t_i分钟内做完,就可以得到奖励r_i,然后总时间是n分钟,小明可以确保在时间段内做完

分析: 

  1. 首先该题一看就是需要贪心,因为他想在规定的时间内拿到更多的金币,所以我们需要思考一下贪心策略,并且这道题也要针对数据去排序,并合理的枚举
  2. 在输入的时侯,应当采用结构体输入或者说是数组输入
  3. 这一点很重要,题目中说了一句话不管选择哪个小游戏,他都能在一个时间段内完成,所以问题的关键在于如何去排布这几个任务的先后顺序

思路: 

  1. 首先我们应对输入的数据进行排序,而排序的规则根据题目的要求来看的话,应当是按照每一个小游戏的价值来进行排序,以此来达到目的,需要注意的是结构体排序需要写cmp函数。
  2. 其次,我们应当从财富的大小去枚举,这样的话就可以保证优先考虑财富值大的游戏。
  3. 这点最重要,那就是要考虑时间上的安排,首先,小明是可以在1分钟以内,完成任何一个游戏,因此,完成游戏的过程就可以看成是一瞬间,而不用看成一个时间段,然后我们应当从大往小去安排时间,因为(见下图)时间越充裕,就更有安排的余地,所以从大往小去枚举,就可以把大时间段的时间安排在小时间段以外,从而把更多的可安排的时间给小时间段B3872 [GESP202309 五级] 巧夺大奖_第1张图片

AC CODE(全部): 

#include
using namespace std;

struct game{//结构体用来存放每个游戏的时间和利益 
	int t;
	int r;
}a[505];

bool cmp(game a,game b){//cmp函数(结构体排序规则) 
	return a.r>b.r;
}
bool vis[505];//用来标记该时间是否空闲 
int sum;//收益和 
int main(){
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i].t);
	}
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i].r);
	}
	
	sort(a+1,a+n+1,cmp);//排序 
	
	for(int i=1;i<=n;i++){
		bool k=0;//用来记录该任务是否能按时完成 
		for(int j=a[i].t;j>=1;j--){//按时间从大到小去枚举 
			if(vis[j]==0){//说明有时间 
				vis[j]=1;//标记,说明该时间已被占用 
				k=1;//该任务可以完成 
				break;
			}
		}
		if(k==1){//若该任务可以完成 
			sum+=a[i].r;//将该任务的收益加入累加器 
		}
	}
	printf("%d",sum);//输出 
	return 0;
}

 

 

你可能感兴趣的:(洛谷题解,算法,c++)