In Competitive Programming 3, the C ++ memorization function is implemented as follows (note maximum N was 8):
#include <algorithm> #include <cmath> #include <cstdio> #include <cstring> using namespace std; int N, target; double dist[20][20], memo[1<<16]; double matching(int bitmask) { if (memo[bitmask] > -0.5) // Already computed? Then return the result if yes return memo[bitmask]; if (bitmask == target) // If all students are already matched then cost is zero return memo[bitmask] = 0; double ans = 2000000000.0; // Infinity could also work int p1, p2; for (p1 = 0; p1 < 2*N; ++p1) // Find first non-matched point if (!(bitmask & (1 << p1))) break; for (p2 = p1 + 1; p2 < 2*N; ++p2) // and pair it with another non-matched point if (!(bitmask & (1 << p2))) ans = min(ans, dist[p1][p2]+matching(bitmask| (1 << p1) | (1 << p2))); return memo[bitmask] = ans; }
and then the main method (driving code)
int main() { int i,j, caseNo = 1, x[20], y[20]; while(scanf("%d", &N), N){ for (i = 0; i < 2 * N; ++i) scanf("%d %d", &x[i], &y[i]); for (i = 0; i < 2*N - 1; ++i) for (j = i + 1; j < 2*N; ++j) dist[i][j] = dist[j][i] = hypot(x[i]-x[j], y[i]-y[j]); // use DP to solve min weighted perfect matching on small general graph for (i = 0; i < (1 << 16); ++i) memo[i] = -1; target = (1 << (2 * N)) - 1; printf("Case %d: %.2lf", caseNo++, matching(0)); } return 0; }
source share