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;
        }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章