1 条题解

  • 0
    @ 2026-1-15 15:38:29

    #include <bits/stdc++.h>
    #define EB emplace_back
    using std::cin;
    using std::cout;
    
    typedef std::vector <int> vector;
    const int N = 11, N2 = 1025, INF = 0x3f3f3f3f;
    
    int n, ALL;
    int S[N];
    int pos[N][N];
    int lt[N][N], rt[N][N];
    int f[N][N][N][N][N2];
    vector hint[N];
    
    inline void down(int &x, const int y) {x > y ? x = y : 0;}
    
    inline int get_trans(int a, int b) {
    	int i, u, v;
    	if (S[b] & ~S[a]) return -1;
    	u = hint[a].back();
    	if (!~pos[b][u]) return hint[a].size();
    	for (i = (int)hint[a].size() - 1; i > 0; --i) {
    		v = u, u = hint[a][i - 1];
    		if (!~pos[b][u] || pos[b][u] > pos[b][v]) break;
    	}
    	return i;
    }
    
    int main() {
    	int i, j = 0, l, r, x, y, d, nl, nr, S, cur, ans = INF;
    	std::ios::sync_with_stdio(false), cin.tie(NULL);
    	memset(pos, -1, sizeof pos), memset(lt, -1, sizeof lt), memset(rt, -1, sizeof rt);
    	cin >> n;
    	for (i = 0; i < n; ++i)
    		for (j = 0; cin >> x && x--; hint[i].EB(x)) ::S[i] |= 1 << x, pos[i][x] = j++;
    	for (i = 0; i < n; ++i)
    		for (j = 0; j < n; ++j)
    			if (i != j) rt[i][j] = get_trans(i, j), lt[i][j] = get_trans(j, i);
    	memset(f, 63, sizeof f), ALL = ~(-1 << n), f[n][0][n][0][0] = 0;
    	for (i = 0; i < n; ++i) f[i][hint[i].size()][n][0][1 << i] = 0;
    	for (S = 0; S <= ALL; ++S)
    		for (i = 0; i <= n; ++i) for (l = (int)hint[i].size(); l >= 0; --l)
    			for (j = 0; j <= n; ++j) for (r = 0; r <= (int)hint[j].size(); ++r)
    				if ((cur = f[i][l][j][r][S]) < INF) {
    					if (S == ALL && i == n && r == (int)hint[j].size()) down(ans, cur);
    					for (x = 0; x < n; ++x) if (!(S >> x & 1)) {
    						if (j == n || (~rt[j][x] && r >= rt[j][x])) down(f[i][l][x][0][S | 1 << x], cur);
    						if (i != n && ~lt[i][x] && !l) for (y = lt[i][x]; y <= (int)hint[x].size(); ++y) down(f[x][y][j][r][S | 1 << x], cur);
    					}
    					if (i != n && !l) down(f[n][0][j][r][S], cur);
    					for (d = 0; d < 9; ++d) {
    						if (j == n) nr = r;
    						else {
    							if (!~pos[j][d] || pos[j][d] > r) continue;
    							nr = r + (r == pos[j][d]);
    						}
    						if (i == n) nl = l;
    						else {
    							if (!l || !~pos[i][d] || pos[i][d] >= l) continue;
    							nl = l - (l - 1 == pos[i][d]);
    						}
    						down(f[i][l][j][nr][S], cur + 1),
    						down(f[i][nl][j][nr][S], cur + 1);
    					}
    				}
    	cout << (ans >= INF ? -1 : ans) << '\n';
    	return 0;
    }
    
    
    • 1

    [CERC2016] 不可见的整数 Invisible Integers

    信息

    ID
    6463
    时间
    1000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者