srm 539

http://mlz000.github.io/2015/07/15/srm-539/

250


Description:

從若干個盒子中任意選擇幾個裝石頭,每個盒子容量都有上下限,一旦選擇使用某個盒子,那麼填裝的石頭數必須在該盒子的上下限容量之間。假設最終填裝的石頭總數爲x ,那麼符合條件x>9000x 有多少個?
數據規模:盒子總數[1,15] , 盒子容量[1,106]

Solution

盒子總數15很容易想到枚舉狀態,把每個的上下限存一下,排個序統計一下答案即可。

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 M = 9000;
vector<pii> a;
class Over9000Rocks {
    public:
        int countPossibilities(vector <int> lowerBound, vector <int> upperBound) {
            int n = lowerBound.size();
            for (int i = 0; i < 1 << n; ++i) {
                int l = 0, r = 0;
                for (int j = 0; j < n; ++j) {
                    if (i >> j & 1) {
                        l += lowerBound[j];
                        r += upperBound[j];
                    }
                }
                l = max(l, M + 1);
                if (l <= r) a.pb(mp(l, r));
            }
            sort(a.begin(), a.end());
            int R = 0, ans = 0;
            for (int i = 0; i < a.size(); ++i) {
                if (a[i].F > R) ans += a[i].S - a[i].F + 1;
                else if (a[i].S > R)    ans += a[i].S - R;
                R = max(R, a[i].S);
            }
            return ans;
        }
};

550


Description

目大意:給定一張圖,有T個點,現在有 n 個人要從0號點分別走到 1 ~ n 號點,每個人都是沿着自己最短路徑走(有多條最短路徑則可任意選一條)。如果在到達終點之前,有個人單獨行動,則認爲這個人是處在危險中的(只有一個人經過某條邊)。問n個人該怎麼走使得處在危險中的人數最少。

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;
int d[N][N], f[N][N], l[N];
bool vis[N];
bool find(int u, int n) {
    for (int i = 1; i <= n; ++i) {
        if (f[u][i] && !vis[i]) {
            vis[i] = 1;
            if (!l[i] || find(l[i], n)) {
                l[i] = u;
                return 1;
            }
        }
    }
    return 0;
}
class SafeReturn {
    public:
        int minRisk(int T, vector <string> streets) {
            int n = streets.size();
            memset(d, 63, sizeof(d));
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    if (streets[i][j] != '-')   d[i][j] = streets[i][j] - '0';
            for (int i = 0; i < n; ++i) d[i][i] = 0;
            for (int k = 0; k < n; ++k)
                for (int i = 0; i < n; ++i)
                    for (int j = 0; j < n; ++j)
                        d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
            for (int i = 1; i <= T; ++i)
                for (int j = 1; j <= T; ++j)
                    if (i != j && d[0][j] + d[j][i] == d[0][i]) f[i][j] = 1;
            int ans = T;
            for (int i = 1; i <= T; ++i) {
                memset(vis, 0, sizeof(vis));
                if (find(i, T)) --ans;
            }
            return ans;
        }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章