http://mlz000.github.io/2015/07/15/srm-539/
250
Description:
從若干個盒子中任意選擇幾個裝石頭,每個盒子容量都有上下限,一旦選擇使用某個盒子,那麼填裝的石頭數必須在該盒子的上下限容量之間。假設最終填裝的石頭總數爲
數據規模:盒子總數
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;
}
};