考虑处理出最大的m+1种方案,这些方案中一定有答案。
以m个冲突的方案为基础进行修改,若全取最大为不合法方案,则由某一个方案修改一个装备可以取到最优答案(会传递下去)
对于某个方案,我们可以尝试遍历它的所有位置,尝试把某个位置上的装备改为仅次于当前装备的装备。\(O(mn)\)
写+调得很慢,按这个速度考场上铁定写不出
// Problem: D. The Strongest Build
// Contest: Codeforces - Educational Codeforces Round 114 (Rated for Div. 2)
// URL: https://codeforces.com/problemset/problem/1574/D
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 7;
#define ll long long
#define ull unsigned long long
int rd() {
int s = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();}
return s * f;
}
int n, m, k, tot, c[maxn];
set<ll, greater<ll> > slots[11];
typedef pair<ull, ull> pii;
set<pii, less<pii> > delta;
set<ull> crash;
ull a[11][maxn], ans[11];
ull b[maxn][11], C[maxn][11];
ull ha(ull *s) {
ull res = 0;
for (int i = 1; i <= n; i++) res = res * 19260817ull + s[i];
return res;
}
bool check(ull *s) {
return (crash.count(ha(s)));
}
ull rres = 0;
int main() {
n = rd();
for (int i = 1; i <= n; i++) {
c[i] = rd();
for (int j = 1; j <= c[i]; j++) {
a[i][j] = rd();
}
ans[i] = a[i][c[i]];
}
m = rd();
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
int x = rd();
b[i][j] = x;
C[i][j] = a[j][x];
}
crash.insert(ha(C[i]));
}
if (check(ans) == false ) {
for (int i = 1; i <= n; i++) printf("%d ", c[i]);
return 0;
}
for (int i = 1; i <= m; i++) {
ull res = 0, pos = 0;
for (int j = 1; j <= n; j++) {
if (b[i][j] > 1) {
ull tmp = C[i][j];
C[i][j] = a[j][b[i][j]-1];
if (check(C[i]) == false) {
ull rest = 0;
for (int k = 1; k <= n; k++) rest += C[i][k];
if (rest > res) {
pos = j;
res = rest;
}
}
C[i][j] = tmp;
}
}
if (pos != 0 && res > rres) {
//printf("pos == %llu res == %llu\n", pos, res);
rres = res;
for (int j = 1; j <= n; j++) {
if (pos == j) ans[j] = lower_bound(a[j]+1,a[j]+c[j]+1, a[j][b[i][j]-1])-a[j];
else ans[j] = lower_bound(a[j]+1, a[j]+c[j]+1, a[j][b[i][j]])-a[j];
}
}
}
for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
return 0;
}