Skip to content

Commit 02b1f64

Browse files
Add files via upload
1 parent 0dc2863 commit 02b1f64

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

Other_Tasks/CF2051_G_Snakes.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**CF2051G Snakes
2+
* Construct a graph G(V, E) such that V = {1, 2, ..., n} and E = {(u, v, w) | the minimum distance snake v must be put to the immediate right of snake u (i.e. s_u - s_v) must be at least w}.
3+
* Now we are just looking for a variation of the shortest hamiltonian path (where we also need to count the number of positions the last snake moves, i.e. the final head position of the last snake).
4+
* This is done with bitmask DP in O(n^2 2^n)
5+
*/
6+
#pragma GCC optimize("Ofast")
7+
#pragma GCC optimize("unroll-loops")
8+
#include <bits/stdc++.h>
9+
using namespace std;
10+
11+
typedef long long ll;
12+
13+
constexpr ll inf = 1e18;
14+
int n, q;
15+
vector<int> heads;
16+
vector<int> tails;
17+
vector<vector<int>> adjmat;
18+
vector<vector<ll>> memo;
19+
ll dp(int u, int avail) {
20+
if (avail == 0) return heads[u];
21+
if (memo[u][avail] != -1) return memo[u][avail];
22+
23+
memo[u][avail] = inf;
24+
int bm = avail;
25+
while (bm) {
26+
int v = __builtin_ctz(bm);
27+
bm ^= (1 << v);
28+
memo[u][avail] = min(memo[u][avail], dp(v, avail ^ (1 << v)) + adjmat[u][v]);
29+
}
30+
31+
return memo[u][avail];
32+
}
33+
34+
int main() {
35+
cin >> n >> q;
36+
heads.assign(n, 0);
37+
tails.assign(n, 0);
38+
adjmat.assign(n, vector<int>(n, 1));
39+
40+
for (int i = 0; i < q; i++) {
41+
int u;
42+
char op;
43+
cin >> u >> op;
44+
u--;
45+
if (op == '+') {
46+
heads[u]++;
47+
for (int v = 0; v < n; v++) {
48+
if (u != v) {
49+
adjmat[u][v] = max(adjmat[u][v], heads[u] - tails[v] + 1);
50+
}
51+
}
52+
} else {
53+
tails[u]++;
54+
}
55+
}
56+
57+
memo.assign(n, vector<ll>(1 << n, -1));
58+
ll ans = inf;
59+
for (int i = 0; i < n; i++) {
60+
ans = min(ans, dp(i, ((1 << n) - 1) ^ (1 << i)));
61+
}
62+
cout << ans + 1 << endl;
63+
64+
return 0;
65+
}

0 commit comments

Comments
 (0)