codeforces 812C Sagheer and Nubian Market (二分+贪心)
On his trip to Luxor and Aswan, Sagheer went to a Nubian market to buy some souvenirs for his friends and relatives. The market has some strange rules. It contains n different items numbered from 1 to n. The i-th item has base cost ai Egyptian pounds. If Sagheer buysk items with indices x1, x2, ..., xk, then the cost of item xj is axj + xj·k for 1 ≤ j ≤ k. In other words, the cost of an item is equal to its base cost in addition to its index multiplied by the factor k.
Sagheer wants to buy as many souvenirs as possible without paying more than S Egyptian pounds. Note that he cannot buy a souvenir more than once. If there are many ways to maximize the number of souvenirs, he will choose the way that will minimize the total cost. Can you help him with this task?
The first line contains two integers n and S (1 ≤ n ≤ 105 and 1 ≤ S ≤ 109) — the number of souvenirs in the market and Sagheer's budget.
The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 105) — the base costs of the souvenirs.
On a single line, print two integers k, T — the maximum number of souvenirs Sagheer can buy and the minimum total cost to buy these ksouvenirs.
谷歌翻译:
在他去卢克索和阿斯旺的旅途中,Sagheer去了一个努比亚市场来为他的亲友购买一些纪念品。这个市场有一些奇怪的规则。它出售这n种不同的商品。第i个纪念品价格ai元。购买时如果购买k个,第i个纪念品的价格就是a[i]+k*i。
Sagheer想要尽可能多地购买纪念品,且价格不超过S埃及镑。他不能购买同一个纪念品多次。如果有很多方法可以最大限度地提高纪念品的数量,他将选择总成本最小的方法。你可以帮助他这个任务吗?
输入
第一行包含两个整数n和S(1≤n≤105和1≤S≤109) - 市场上的纪念品数量和Sagheer的预算。
第二行包含n个空格分隔的整数a1,a2,...,an(1≤ai≤105) - 纪念品的基本费用。
产量
在单行上,打印两个整数k,T - Sagheer可以购买的纪念品的最大数量以及购买这些纪念品的最低总成本。
这不就是个naive的二分吗(flag),(一小时后)mmp才调好
二分购买mid个物品,重新计算每个物品的现价,排序后计算购买mid个价格最小的总花费是否小于S就可以了
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[100005];
ll newa[100005];
ll s,n;
ll l,r,mid;
ll ans;
int main()
{
ios::sync_with_stdio(false);
cin >> n >> s;
for (int i = 1;i <= n;i++)
{
cin >> a[i];
}
l = 0;r = n;ll sum;
while (l < r)
{
sum = 0;
mid = (l+r+1) >> 1;
for (int i = 1;i <= n;i++)
{
newa[i] = a[i] + i * mid;
}
sort(newa+1,newa+n+1);
for (int i = 1;i <= mid;i++)
{
sum += newa[i];
}
if (sum > s) r = mid - 1;
else l = mid;
}
cout << l << " ";
for (int i = 1;i <= n;i++) newa[i] = a[i] + i * l;
sort(newa+1,newa+n+1);
sum = 0;
for (int i = 1;i <= l;i++) sum = sum + newa[i];
cout << sum << endl;
return 0;
}

浙公网安备 33010602011771号