1. 程式人生 > >「日常訓練」More Cowbell(Codeforces Round #334 Div.2 B)

「日常訓練」More Cowbell(Codeforces Round #334 Div.2 B)

題意與分析(CodeForces 604B)

題意是這樣的:\(n\)個數字,\(k\)個盒子,把\(n\)個數放入\(k\)個盒子中,每個盒子最多隻能放兩個數字,問盒子容量的最小值是多少(水題)
不要看到這種題目什麼都不想,看見最大容量最小值就是起手一個二分,這題運用貪心的思想會更簡單。
想一想紫書上有一題是類似的,兩個人坐船過河的,也是同樣的思路。
我們一定要注意到這樣一個結論:如果第一個數沒法和某一個數放在一起,那麼大於等於它的數一定都只能一個單獨的盒子了。設這個數是第\(p\)個,那麼就是有\(n-(p+1)+1=n-p\)個數是一個盒子放著的,而有\(\frac p2\)個數是合併著放在一起的。顯然有\(n-p+\frac p2=k\)

,代入化簡有\(2n-2p+p=2k\),從而有\(p=2n-2k\),也就是前\(2(n-k)\)個數必須手拉手放在一起才能夠滿足題意。但是呢,有可能k比n大,這麼直接寫就有可能出錯。我們不妨從中間往兩邊擴散,測試掉前\(k\)對直到不合法為止,然後讓它與最後一個最大的單個比較一下就行了。

程式碼

/* ACM Code written by Sam X or his teammates.
 * Filename: cfr334d2b.cpp
 * Date: 2018-11-05
 */

#include <bits/stdc++.h>

#define INF 0x3f3f3f3f
#define PB emplace_back
#define MP make_pair
#define fi first
#define se second
#define rep(i,a,b) for(repType i=(a); i<=(b); ++i)
#define per(i,a,b) for(repType i=(a); i>=(b); --i)
#define ZERO(x) memset(x, 0, sizeof(x))
#define MS(x,y) memset(x, y, sizeof(x))
#define ALL(x) (x).begin(), (x).end()

#define QUICKIO                  \
    ios::sync_with_stdio(false); \
    cin.tie(0);                  \
    cout.tie(0);
#define DEBUG(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)

using namespace std;
using pi=pair<int,int>;
using repType=int;
using ll=long long;
using ld=long double;
using ull=unsigned long long;

int n,k,s[100005];

int
main()
{
    scanf("%d%d", &n, &k);
    rep(i,1,n)
    {
        scanf("%d", &s[i]);
    }
    int ans=0;
    int l=n-k,r=n-k+1;
    for(;l>=1&&r<=n;--l,++r)
        ans=max(ans,s[l]+s[r]);
    ans=max(ans,s[n]);
    cout<<ans<<endl;
    return 0;
}