Skip to content

Commit 2fe5945

Browse files
committed
a2
1 parent 20c370f commit 2fe5945

17 files changed

+639
-30
lines changed

2022/a2/back/d-american.cpp

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
4+
typedef long long ll;
5+
typedef pair<int, int> pii;
6+
7+
template<typename T>
8+
void printv(vector<T> &v) {
9+
for(int i = 0; i < v.size(); i++) {
10+
cout << v[i];
11+
if(i < v.size() - 1)
12+
cout << " ";
13+
}
14+
cout << endl;
15+
}
16+
17+
ll dijkstra(
18+
vector<vector<ll>> &cost,
19+
vector<vector<ll>> &adj,
20+
int j, int k, int mask
21+
) {
22+
// dijkstra j => k
23+
priority_queue<
24+
pair<ll, int>, // cost, node
25+
vector<pair<ll, int>>,
26+
greater<pair<ll, int>>
27+
> q;
28+
int u, v, i;
29+
ll d;
30+
q.emplace(0, j);
31+
while(!q.empty()) {
32+
tie(d, u) = q.top(); q.pop();
33+
if(u == k) return d;
34+
if(!((mask >> u) & 1)) continue;
35+
mask = mask ^ (1 << u);
36+
for(int v : adj[u]) {
37+
if(!((mask >> v) & 1)) continue;
38+
q.emplace(d + cost[u][v], v);
39+
40+
}
41+
}
42+
throw runtime_error("dijkstra: cannot find path j => k");
43+
}
44+
45+
/*
46+
g++ -std=c++11 d-american.cpp -o k
47+
18 < 32 == 2^5
48+
2^18 = 262,144
49+
*/
50+
int main() {
51+
ios_base::sync_with_stdio(0); cin.tie(0);
52+
int n, m;
53+
int i, j, k, l;
54+
int u, v, s;
55+
int mask;
56+
ll d;
57+
cin >> n >> m;
58+
vector<vector<ll>> cost(n, vector<ll>(n, numeric_limits<ll>::max())); // adj-mtx
59+
vector<vector<ll>> adj(n); // adj-list
60+
for(i = 0; i < m; i++) {
61+
cin >> u >> v >> d;
62+
u -= 1; v -= 1;
63+
cost[u][v] = d;
64+
cost[v][u] = d;
65+
adj[u].push_back(v);
66+
adj[v].push_back(u);
67+
}
68+
cin >> s;
69+
vector<ll> memo(1 << n);
70+
for(i = 0; i < n; i++) {
71+
j = (1 << i); // 1 = 2^0
72+
cost[j][j] = 0;
73+
j = (i << 18) + (1 << i); // f({i}, i) = 0;
74+
memo[j] = cost[s][i];
75+
}
76+
int key;
77+
for(i = 2; i < (1 << n); i++) {
78+
// iterate over subsets X where bitmasks equal i
79+
if((i >> s) & 1)
80+
// X contains s
81+
continue;
82+
for(j = 0; j < n; j++) {
83+
// compute f(X, j)
84+
if(!((i >> j) & 1))
85+
// node j is not in X
86+
continue;
87+
l = (i ^ (1 << j)); // X \ {j}
88+
if(!l)
89+
// X \ {j} == {} empty set
90+
continue;
91+
key = (j << 18) + i;
92+
for(k = 0; k < n; k++) {
93+
// consider subset X \ {j}
94+
// where last visited node is k
95+
if(!((l >> k) & 1))
96+
// node k is not in the set
97+
continue;
98+
// do dijkstra between k, j using nodes in X + {s}
99+
// f(X \ {j}, k) + dijkstra(k, j)
100+
mask = (i | (1 << s));
101+
d = dijkstra(cost, adj, j, k, mask);
102+
// compute f(X \ {j}, k) + d(k, j)
103+
d = memo[(k << 18) + l] + d;
104+
// memoize f(X, j) = f(X \ {j}, k) + d(k, j)
105+
memo[key] = min(memo[key], d);
106+
}
107+
}
108+
}
109+
ll o = numeric_limits<ll>::max();
110+
mask = (1 << n) - 1;
111+
for(i = 0; i < n; i++) {
112+
d = dijkstra(cost, adj, i, s, mask);
113+
key = (1 << n) - 1 + (i << 18);
114+
d = memo[key] + d;
115+
o = min(d, o);
116+
}
117+
cout << o << endl;
118+
119+
return 0;
120+
}
121+

2022/a2/back/f-star.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
4+
typedef long long ll;
5+
typedef pair<int, int> pii;
6+
7+
bool DEBUG = false;
8+
9+
ll MODVAL = 1000000000 + 7;
10+
11+
//vector<ll> FACTORIAL(1001);
12+
vector<vector<ll>> CHOOSE(1001, vector<ll>(1001));
13+
14+
inline ll modmul(ll a, ll b) {
15+
return (a * b) % MODVAL;
16+
}
17+
18+
inline ll modadd(ll a, ll b) {
19+
return (a + b) % MODVAL;
20+
}
21+
22+
/*
23+
2D DP of divide and conquer
24+
g++ -std=c++11 f-star.cpp -o k
25+
26+
This works! Creating another clean version for submission.
27+
*/
28+
void main(int argc, char *argv[]) {
29+
30+
int i, j;
31+
int n, k;
32+
int N, K;
33+
int min_nK;
34+
ll c, d;
35+
36+
//FACTORIAL[0] = 1;
37+
//for(n = 1; n <= 1000; n++)
38+
// FACTORIAL[n] = (FACTORIAL[n - 1] * n) % MODVAL;
39+
40+
for(n = 1; n <= 1000; n++) {
41+
CHOOSE[n][0] = 1;
42+
for(k = 1; k < n; k++) {
43+
CHOOSE[n][k] = modadd(CHOOSE[n-1][k-1], CHOOSE[n-1][k]);
44+
}
45+
CHOOSE[n][n] = 1;
46+
47+
}
48+
49+
cin >> N >> K;
50+
vector<vector<ll>> memo(N + 1, vector<ll>(K + 1, 0));
51+
52+
memo[1][0] = 1;
53+
memo[2][0] = 2;
54+
55+
for(n = 3; n <= N; n++) {
56+
min_nK = min(n / 2, K);
57+
for(k = 0; k <= min_nK; k++) {
58+
// memoize f(n, k)
59+
c = 0;
60+
if(DEBUG) printf("(n=%d, k=%d) \n", n, k);
61+
for(i = 1; i <= n - 2; i++) {
62+
for(j = 0; j <= k - 1; j++) {
63+
if(DEBUG) printf(" f(%d, %d) = %lld = f(i, j) \n", i, j, memo[i][j]);
64+
if(DEBUG) printf(" f(%d, %d) = %lld = f(n-i-1, k-1-j) \n", n - i - 1, k - 1 - j, memo[n - i - 1][k - 1 - j]);
65+
if(DEBUG) printf(" choose(%d, %d) = %lld = choose(n-1, i) \n", n-1, i, CHOOSE[n - 1][i]);
66+
d = modmul(
67+
modmul(memo[i][j], CHOOSE[n - 1][i]),
68+
memo[n - i - 1][k - 1 - j]
69+
);
70+
if(DEBUG) printf(" sum = %lld \n", d);
71+
c = modadd(c, d);
72+
}
73+
}
74+
// edge subproblems
75+
if(DEBUG) printf("f(%d, %d) = %lld = f(n-1, k) \n", n-1, k, memo[n - 1][k]);
76+
c = modadd(c, modmul(2, memo[n - 1][k]));
77+
memo[n][k] = c;
78+
if(DEBUG) printf("f(n=%d, k=%d)=%lld \n", n, k, memo[n][k]);
79+
}
80+
}
81+
82+
cout << memo[N][K] << endl;
83+
84+
return 0;
85+
}
86+
87+
int main(int argc, char *argv[]) {
88+
ios_base::sync_with_stdio(0); cin.tie(0);
89+
if (argc > 1) {
90+
string arg = argv[1];
91+
DEBUG = arg == "debug";
92+
}
93+
94+
int i, j;
95+
int n, k;
96+
int N, K;
97+
int min_nK;
98+
ll c, d;
99+
100+
//FACTORIAL[0] = 1;
101+
//for(n = 1; n <= 1000; n++)
102+
// FACTORIAL[n] = (FACTORIAL[n - 1] * n) % MODVAL;
103+
104+
for(n = 1; n <= 1000; n++) {
105+
CHOOSE[n][0] = 1;
106+
for(k = 1; k < n; k++) {
107+
CHOOSE[n][k] = modadd(CHOOSE[n-1][k-1], CHOOSE[n-1][k]);
108+
}
109+
CHOOSE[n][n] = 1;
110+
111+
}
112+
113+
return 0;
114+
}
115+

0 commit comments

Comments
 (0)