QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#446069 | #8005. Crossing the Border | nKessi | WA | 75ms | 8292kb | C++14 | 3.2kb | 2024-06-16 20:56:20 | 2024-06-16 20:56:21 |
Judging History
answer
/*
世界の果てさえ
【世界的尽头在何处】
仆らは知らない
【我们也无从知晓】
*/
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <random>
#include <ctime>
#define pr pair <int, int>
#define mr make_pair
#define LL long long
#define ls tree[p].L
#define rs tree[p].R
using namespace std;
const int MAXN = 23, MAXM = 12, inf = 0x3f3f3f3f, Mod = 998244353;
int n, W, w[MAXN], c[MAXN];
int dp1[1 << MAXM][1 << MAXM], dp2[1 << MAXM][1 << MAXM];
int lsh1[(1 << MAXM) + 5], lsh2[(1 << MAXM) + 5];
int a1[(1 << MAXM) + 5], a2[(1 << MAXM) + 5], b1[(1 << MAXM) + 5], b2[(1 << MAXM) + 5];
vector <int> v1[(1 << MAXM) + 5], v2[(1 << MAXM) + 5];
void read(int &x) {
x = 0; bool f = 1; char C = getchar();
for(; C < '0' || C > '9'; C = getchar()) if(C == '-') f = 0;
for(; C >= '0' && C <= '9'; C = getchar()) x = (x << 1) + (x << 3) + (C ^ 48);
x = (f ? x : -x);
}
bool cmp1(int x, int y) { return a1[x] > a1[y]; }
bool cmp2(int x, int y) { return a2[x] > a2[y]; }
int main() {
read(n); read(W);
for(int i = 1; i <= n; i ++) read(w[i]), read(c[i]);
int m = (n >> 1);
for(int i = 0; i < (1 << m); i ++) {
for(int j = 0; j < m; j ++) if(i >> j & 1) a1[i] += w[j + 1], b1[i] = max(b1[i], c[j + 1]);
}
for(int i = 0; i < (1 << (n - m)); i ++) {
for(int j = 0; j < n - m; j ++) if(i >> j & 1) a2[i] += w[j + m + 1], b2[i] = max(b2[i], c[j + m + 1]);
}
for(int i = 0; i < (1 << m); i ++) {
for(int j = i; j; j = (j - 1) & i) v1[i].emplace_back(j);
v1[i].emplace_back(0); sort(v1[i].begin(), v1[i].end(), cmp1);
}
for(int i = 0; i < (1 << (n - m)); i ++) {
for(int j = i; j; j = (j - 1) & i) v2[i].emplace_back(j);
v2[i].emplace_back(0); sort(v2[i].begin(), v2[i].end(), cmp2);
}
// printf("$%d$", m);
dp2[0][0] = 1;
for(int i = 0; i < (1 << m); i ++) {
for(int j = 0; j < (1 << (n - m)); j ++) {
if(i == 0 && j == 0) continue;
// printf("|%d %d|\n", i, j);
if(i == 0) {
dp1[i][j] = inf;
for(int k = j; k; k = (k - 1) & j) {
if(__builtin_clz(k) != __builtin_clz(j) || a2[k] > W) continue;
if(dp1[i][j ^ k] + b2[k] < dp1[i][j]) dp1[i][j] = dp1[i][j ^ k] + b2[k], dp2[i][j] = dp2[i][j ^ k];
else if(dp1[i][j ^ k] + b2[k] == dp1[i][j]) dp2[i][j] = (dp2[i][j] + dp2[i][j ^ k]) % Mod;
}
continue;
}
int u = v2[j].size(); int ans1 = inf, ans2 = 0;
for(auto k : v1[i]) {
if(__builtin_clz(k) ^ __builtin_clz(i)) continue;
while(u - 1 >= 0 && a1[k] + a2[v2[j][u - 1]] <= W) {
u --;/// printf("?%d %d?", a1[k] + a2[v2[j][u]], v2[j][u]);
if(dp1[i ^ k][j ^ v2[j][u]] + max(b1[k], b2[v2[j][u]]) < ans1) {
ans1 = dp1[i ^ k][j ^ v2[j][u]] + max(b1[k], b2[v2[j][u]]), ans2 = dp2[i ^ k][j ^ v2[j][u]];
}
else if(dp1[i ^ k][j ^ v2[j][u]] + max(b1[k], b2[v2[j][u]]) == ans1) ans2 = (ans2 + dp2[i ^ k][j ^ v2[j][u]]) % Mod;
}
}
dp1[i][j] = ans1; dp2[i][j] = ans2;
// printf("?%d %d %d %d?\n", i, j, ans1, ans2);
}
}
printf("%d %d", dp1[(1 << m) - 1][(1 << (n - m)) - 1], dp2[(1 << m) - 1][(1 << (n - m)) - 1]);
return 0;
}
/*
5 5
3 5
1 4
2 3
2 2
2 1
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 4136kb
input:
5 5 3 5 1 4 2 3 2 2 2 1
output:
9 4
result:
ok 2 number(s): "9 4"
Test #2:
score: -100
Wrong Answer
time: 75ms
memory: 8292kb
input:
18 10000000 956231 904623 1692946 1796774 1081323 1170319 3218792 2542661 3183376 3037270 1869132 1442561 35436 35018 1564635 1939950 1847344 2006043 755870 899310 1671882 2057413 1369264 1338951 3132483 3504034 2056224 1825640 1840949 1562071 1514040 1405352 2300821 2421801 2466540 3004920
output:
9458090 9
result:
wrong answer 1st numbers differ - expected: '9391997', found: '9458090'