超市有n种不同的商品(从1开始编号),第i种商品有一个基本花费b_ibi。
小白要来买东西,如果小白买了k件商品,编号分别为x_1x1、x_2x2、..、x_kxk,那么物品x_jxj的花费为b_{x_j}bxj+x_j*kxj∗k (1<=j<=k)。也就是说,物品的花费等于它的基本花费加上它的编号乘上k。
小白想要在花费不超过SP的情况下买尽量多的物品。注意,一种物品最多买一件。
输入
第一行两个整数,n和SP(1<=n<=10^5105,1<=SP<=10^9109),含义如上。
第二行n个整数b_1b1、b_2b2,,,b_nbn (1<=b_ibi<=10^5105).
输出
将小白最多买的物品数k和买k件物品的最少花费输出到一行
样例输入
3 11 2 3 5
样例输出
2 11
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
ll n,sp,sum;
const int maxn=1e5+5;
ll b[maxn],c[maxn];
bool solve(ll k)
{
sum=0;
for(ll i=1;i<=n;i++)
{
c[i]=b[i]+i*k;
}
sort(c+1,c+n+1);
for(ll i=1;i<=k;i++)
{
sum+=c[i];
if(sum>sp) return false;
}
return true;
}
int main()
{
scanf("%lld%lld",&n,&sp);
for(ll i=1;i<=n;i++)
scanf("%d",&b[i]);
// for(int i=1;i<=n;i++)
// {
// if(solve(i)) cout<<i<<endl;
// }
ll l=1,r=n; ll k=0;
ll m=0,ans=0;
while(l<r)
{//cout<<l<<' '<<r<<endl;
m=l+(r-l+1)/2;
//m=(l+r+1)>>1;
if(solve(m))
{ k=m;
ans=sum;
l=m;
}
else
{
r=m-1;
}
}
printf("%lld %lld\n",k,ans);
return 0;
}
/*
3 11
2 3 5
*/
- 我写的蜜汁二分,第一次m=l+(l-r)/2; l=m+1;r=m;
- 百发百wa,虽然样例是过的,改成m+1,l,r都-1才能过,心情复杂
- 131072K
超市有n种不同的商品(从1开始编号),第i种商品有一个基本花费b_ibi。
小白要来买东西,如果小白买了k件商品,编号分别为x_1x1、x_2x2、..、x_kxk,那么物品x_jxj的花费为b_{x_j}bxj+x_j*kxj∗k (1<=j<=k)。也就是说,物品的花费等于它的基本花费加上它的编号乘上k。
小白想要在花费不超过SP的情况下买尽量多的物品。注意,一种物品最多买一件。
输入
第一行两个整数,n和SP(1<=n<=10^5105,1<=SP<=10^9109),含义如上。
第二行n个整数b_1b1、b_2b2,,,b_nbn (1<=b_ibi<=10^5105).
输出
将小白最多买的物品数k和买k件物品的最少花费输出到一行
样例输入
3 11 2 3 5
样例输出
2 11