srm 536

250



Description

給n個數,你可以合併任意k個數,合併之後出現的數是a[x]+a[y]+...+a[x]/k 。問最後剩下的數字最大是多少

Solution

類似於霍夫曼樹,每次貪心把最小的兩個數合併即可。

Code

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define F first
#define S second
typedef long long LL;
typedef pair<int, int> pii;
const int N = 55;
class MergersDivOne {
    public:
        double findMaximum(vector <int> revenues) {
            int n = revenues.size();
            sort(revenues.begin(), revenues.end());
            double ans = (revenues[0] + revenues[1]) * 0.5;
            for (int i = 2; i < n; ++i) {
                ans = (ans + revenues[i]) * 0.5;
            }
            return ans;
        }
};

500



Description:

給n(n50 )個骰子,每個骰子的用x個面分別爲1x,x109 。問同時擲n個骰子,最有可能出現的點數是多少,多解輸出最小值

Solution

不妨考慮兩兩組合,考慮當前可能擲出的點數最大是len,極值點位置是pos,(0-base)。整個圖像應該是先遞增,不變,再遞減。中間不變的地方是極值點。
新來一個骰子,如果len2posdice[i] ,考慮最小的那個極值點的變化,比如和的序列是
1 2 3 4 ,len = 4, pos = 0(極值點爲1)。新來的序列是
3 2 1。顯然新來的序列最右端與pos對齊即產生新的極值點。
如果len2pos<dice[i] ,那麼新極值點就是新列表中間點。
爲了考慮方便,我們將dice數組降序排列。由於考慮的是0-base,最後答案爲pos+n

Code:

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define F first
#define S second
typedef long long LL;
typedef pair<int, int> pii;
class RollingDiceDivOne {
    public:
        long long mostLikely(vector <int> dice) {
            sort(dice.begin(), dice.end(), greater<int>());
            LL len = dice[0], pos = 0;
            int n = dice.size();
            for (int i = 1; i < n; ++i) {
                if (len - 2 * pos >= dice[i]) pos += dice[i] - 1;
                else pos = (len + dice[i] - 2) / 2;
                len += dice[i] - 1;
            }
            return pos + n;
        }
};
發佈了86 篇原創文章 · 獲贊 7 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章