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;
}