题意:给了n个物品,每个物品的价值为ai,你可以选取其中的k个,代价是k个ai的和加上他们的下标乘k的和。
问,在给定最大代价S的条件下,最多能取几个,取的最多的情况下,代价是多少。
分析:对能取几个进行二分,每次判断的时候,将原来的数组对ai+i*mid排序,取前mid个,看是否大于S。
以下是代码:
ll n, s, ans1, ans2;
struct lx {
ll id, v, k;
friend bool operator<(const lx &a, const lx &b) {
return a.v + a.id*a.k < b.v + b.id*b.k;
}
}tmp[MAXN], a[MAXN];
bool check(int mid) {
for (int i = 1; i <= n; ++i)tmp[i] = a[i], tmp[i].k = mid;
sort(tmp + 1, tmp + 1 + n);
ll sum = 0;
for (int i = 1; i <= mid; ++i) {
sum += tmp[i].v + tmp[i].id*tmp[i].k;
}
ans2 = sum;
if (sum > s)return false;
else return true;
}
int main()
{
scanf("%I64d%I64d", &n, &s);
for (int i = 1; i <= n; ++i) {
scanf("%I64d", &a[i].v);
a[i].id = i;
}
int l = 0, r = n + 1;
while (l < r) {
int mid = (l + r) >> 1;
if (check(mid)) {
l = mid + 1;
}
else r = mid;
}
l--; ans1 = l;
check(l);
printf("%I64d %I64d\n", ans1, ans2);
}