超市有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