srm 551

250


Description

题意:一个长度最多$50$的字符串,每次操作可以交换相邻的两个字符,问,经过最多$MaxSwaps$次交换之后,最多能让多少个相同的字符连起来

Solution

枚举一个字符,让其他字符往这里即可,取最小即可

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#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;
struct ColorfulChocolates {
int maximumSpread(string chocolates, int maxSwaps) {
int ans = 0;
int n = chocolates.size();
for (int i = 0; i < n; ++i) {
string s = chocolates;
int now = 1;
vector<int> a;
for (int j = i - 1; j >= 0; --j)
if (s[j] == s[i]) a.pb(i - j - now), ++now;
now = 1;
for (int j = i + 1; j < n; ++j)
if (s[j] == s[i]) a.pb(j - i - now), ++now;
sort(a.begin(), a.end());
int cnt = maxSwaps;
int t = 1;
for (int i = 0; i < a.size(); ++i)
if (cnt - a[i] >= 0) {
cnt -= a[i];
++t;
}
ans = max(ans, t);
}
return ans;
}
};

450


Description

一个有向图,顶点标号$0\sim n-1$,每个点会选择优先走他能到达的编号最小的点,现在想通过去掉一些边使得可以从$0$走到$n-1$,求最少要去掉的边数

Solution

考虑类似于$floyd$的做法,$d[i][j]$表示$i$走到$j$需要最少删多少条边,直接$dp$即可

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <bits/stdc++.h>//dp
#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, inf = 1e6;
int d[N][N];
struct ColorfulWolves {
int getmin(vector <string> colormap) {
int n = colormap.size();
for (int i = 0; i < n; ++i) {
int now = 0;
for (int j = 0; j < n; ++j) {
if (colormap[i][j] == 'Y') d[i][j] = now++;
else d[i][j] = inf;
}
}
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]);
return d[0][n - 1] == inf ? -1 : d[0][n - 1];
}
};