首页 > 代码库 > Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market 二分答案 +排序

Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market 二分答案 +排序

Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market

二分答案 +排序
题意 有 a[ i ] 个数 要求选最多的数 使其和不超过 S ,且在此情况下,和最小
选最多数情况下 和最小 且 每个数有加成
如果选了 k个数 那么加成后 就是 a[ i ] + k*i ;


题解 二分mid 表示选了个数
加成一下,将加成以后结果排序一下 , 若前 mid数 和大于 s 则此方案不可行

PS 要用 long long ..... 还有 codeforces 要用 %I64d

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iomanip>
 4 #include <algorithm>
 5 #define ll long long 
 6 using namespace std ; 
 7 
 8 const ll maxn = 100011 ; 
 9 ll n,s,l,r,mid ; 
10 ll a[maxn],b[maxn] ; 
11 
12 inline bool check(ll mid) 
13 {
14     ll sum = 0 ; 
15     for(ll i=1;i<=n;i++) b[ i ] = a[ i ] + 1ll*i*mid ;
16     sort(b+1,b+n+1) ; 
17     for(ll i=1;i<=mid;i++) 
18         sum+=b[ i ] ; 
19     return sum <= s ; 
20 }
21 
22 int main() 
23 {
24     scanf("%I64d%I64d",&n,&s) ; 
25     for(ll i=1;i<=n;i++) scanf("%I64d",&a[ i ]),b[ i ] = a[ i ] ;
26     sort(b+1,b+n+1) ; 
27      l = 0 ; r = n ; 
28     while(l<r) 
29     {
30         mid = (l+r+1)>>1 ;
31         if(check(mid)) l = mid ; 
32             else r = mid - 1 ; 
33     }
34     printf("%I64d ",l) ; 
35     ll sum = 0 ;
36     for(ll i=1;i<=n;i++) b[ i ] = a[ i ] + 1ll*i*l ;
37     sort(b+1,b+n+1) ; 
38     for(ll i=1;i<= l ;i++) 
39         sum+=b[ i ] ; 
40     printf("%I64d\n",sum) ; 
41     return 0 ; 
42 }

 

Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market 二分答案 +排序