QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#626803#8005. Crossing the Borderpbk5418WA 0ms22480kbC++142.5kb2024-10-10 13:08:202024-10-10 13:08:20

Judging History

你现在查看的是最新测评结果

  • [2024-10-10 13:08:20]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:22480kb
  • [2024-10-10 13:08:20]
  • 提交

answer

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int N = 22,P = 998244353;
int n,nn,W,R,S,T,mx[1 << N | 5],wt[1 << N | 5],f[1 << N | 5],g[1 << N | 5];
struct sib {int w,c;} e[31];
struct Node {int w,c,id;} ;
vector <Node> a[1 << 11 | 5];
vector <int> b[1 << 11 | 5];
int add(int x){return x >= P ? x - P : x;}
int main() {
	scanf("%d%d",&n,&W);
	for (int i = 0; i < n; i ++) scanf("%d%d",&e[i].w,&e[i].c);
	sort(e,e + n,[](sib x,sib y){return x.c > y.c;});
	nn = n / 2;
	S = 1 << n,T = 1 << nn,R = (1 << n - nn);
	memset(f,0x3f,sizeof(f));
	for (int s = 1; s < S; s ++) {
		int i = s & -s,j = __lg(i);
		mx[s] = max(e[j].c,mx[s ^ i]);
		wt[s] = wt[s ^ i] + e[j].w;
	}
	f[0] = 0,g[0] = 1;
	for (int x = 0; x < R; x ++) {
		b[x].push_back(x);
		for (int X = (x + 1) | x; X < R; X = (X + 1) | x) {
			if (X - x > x && wt[(X - x) << nn] <= W)
				f[X << nn] = min(f[X << nn],f[x << nn] + mx[(X - x) << nn]);
			b[x].push_back(X);
		}
		sort(b[x].begin(),b[x].end(),[&](int A,int B){return wt[(A - x) << nn] > wt[(B - x) << nn];});
	}
	for (int Y = 1; Y < T; Y ++) {
		for (int y = (Y - 1) & Y; y > 0; y = Y & (y - 1)) 
			if (Y - y > y) a[Y].push_back(Node{wt[Y - y],mx[Y - y],y});
		a[Y].push_back(Node{wt[Y],mx[Y],0});
		sort(a[Y].begin(),a[Y].end(),[](Node x,Node y){return x.w < y.w;});
		for (int x = 0; x < R; x ++) {
			int j = 0,F = 0x3f3f3f3f;
			for (int X : b[x]) {
				int ss = W - wt[(X - x) << nn],to = (X << nn) + Y;
				while (j < a[Y].size() && a[Y][j].w <= ss) {
					int k = (x << nn) + a[Y][j].id;
					if (f[k] + a[Y][j].c < F) F = f[k] + a[Y][j].c;
					j ++;
				}
				f[to] = min(f[to],F);
			}
		}
	}
//	for (int x = 0; x < R; x ++)
//		for (int X = (x + 1) | x; X < R; X = (X + 1) | x)
//			if (X - x > x && wt[(X - x) << nn] <= W && f[x << nn] + mx[(X - x) << nn] == f[X << nn])
//				g[X << nn] = add(g[X << nn] + g[x << nn]);
//	for (int Y = 1; Y < T; Y ++) {
//		for (int x = 0; x < R; x ++) {
//			int j = 0,F = 0x3f3f3f3f,G = 0;
//			for (int X : b[x]) {
//				int ss = W - wt[(X - x) << nn],to = (X << nn) + Y;
//				while (j < a[Y].size() && a[Y][j].w <= ss) {
//					int k = (x << nn) + a[Y][j].id;
//					if (f[k] + a[Y][j].c < F) F = f[k] + a[Y][j].c,G = 0;
//					if (f[k] + a[Y][j].c == F) G = add(G + g[k]);
//					j ++;
//				}
//				if (f[to] == F) g[to] = add(g[to] + G);
//			}
//		}
//	}
//	for (int i = 0; i < S; i ++)
//		cout << i << " " << f[i] << " " << g[i] << endl;
	printf("%d %d",f[S - 1],g[S - 1]);
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 22480kb

input:

5 5
3 5
1 4
2 3
2 2
2 1

output:

9 0

result:

wrong answer 2nd numbers differ - expected: '4', found: '0'