CF812C Sagheer and Nubian Market

Description

洛谷传送门

Solution

注意到题目要求我们计算出最多能买多少个纪念品,所以容易想到二分。

我们二分最多能买多少个纪念品,把每个纪念品的实际花费计算出来,从小到大排个序,取出前 \(mid\) 个,判断花费是否合法即可。

Code

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 1e5 + 10;
int n, s, cnt, ans, res;
int a[N], b[N];

inline bool check(int mid){
	for(int i = 1; i <= n; i++)
		b[i] = a[i] + i * mid;//计算每个物品的实际花费。
	sort(b + 1, b + 1 + n);
	res = 0;
	for(int i = 1; i <= mid && res <= s; i++)//取前 k 个物品,总花费小于等于 s
		res += b[i];
	return res <= s;
}

int main(){
	scanf("%d%d", &n, &s);
	for(int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	int l = 0, r = n;
	while(l <= r){
		int mid = (l + r) >> 1;
		if(check(mid)) cnt = mid, ans = res, l = mid + 1;//二分边界向来不好调,合法时直接更新答案即可。
		else r = mid - 1;
	}
	printf("%d %d\n", cnt, ans);
	return 0;
}

End

posted @ 2021-10-11 22:20  xixike  阅读(23)  评论(0编辑  收藏  举报