QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#779264#8005. Crossing the BorderMirasycleWA 0ms7684kbC++142.2kb2024-11-24 18:05:462024-11-24 18:05:49

Judging History

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

  • [2024-11-24 18:05:49]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:7684kb
  • [2024-11-24 18:05:46]
  • 提交

answer

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb emplace_back
#define mp make_pair
using namespace std;
typedef long long ll;
const int maxn=24;
const int maxs=(1<<24);
const int inf=0x3f3f3f3f;
const int mod=998244353;
int a[maxn],b[maxn],mx[maxs],n,W;
pair<int,int> dp[maxs]; ll sum[maxs];
void add(int &x,int y){ x=x+y>=mod?x+y-mod:x+y; }
int lowbit(int x){ return x&-x; }
int maxbit(int s){ return (1<<mx[s]-1); }
bool cmp(int x,int y){ return sum[x]>sum[y]; }
void upd(pair<int,int>& f,pair<int,int> g){
	if(f.fi>g.fi) f=g;
	else if(f.fi==g.fi) add(f.se,g.se);
}
int main(){
	cin>>n>>W;
	for(int i=1;i<=n;i++) cin>>a[i]>>b[i];
	for(int i=1;i<=n;i++)
		for(int j=2;j<=n;j++)
			if(b[j-1]>b[j]) swap(b[j-1],b[j]),swap(a[j-1],a[j]);
	for(int i=1;i<=n;i++) sum[1<<i-1]=a[i];
	for(int s=1;s<(1<<n);s++){
		sum[s]=sum[s-lowbit(s)]+sum[lowbit(s)];
		dp[s]=mp(inf,0); 
		for(int j=1;j<=n;j++)
			if((s>>j-1)&1) mx[s]=j;
	}
	int m=n/2; dp[0]=mp(0,1);
	for(int s=1;s<(1<<m);s++)//L部分更新 dp
		for(int i=s-maxbit(s);;i=(i-1)&s){
			if(sum[s-i]<=W){// s-i 为新加入部分 
				pair<int,int> tmp=dp[i]; if(tmp.fi==inf) continue;
				tmp.fi+=b[mx[s]]; upd(dp[s],tmp);
			}
			if(!i) break;
		}
	vector<vector<int> > u(1<<n-m);//R 放的是 i 的超集且 i 不含其超集的最高位 
	for(int s=1;s<(1<<n-m);s++)
		for(int i=s-maxbit(s);;i=(i-1)&s){
			if(sum[(s-i)<<m]<=W) u[i].pb(s<<m); 
			if(!i) break;
		}
	for(int s=0;s<(1<<n-m);s++) sort(u[s].begin(),u[s].end(),cmp);
	
	vector<vector<int> > v(1<<m);//L
	for(int s=0;s<(1<<m);s++){//子集 
		for(int i=s;;i=(i-1)&s){
			if(sum[s-i]<=W) v[s].pb(i);
			if(!i) break;
		}
		sort(v[s].begin(),v[s].end(),cmp);
	}
	for(int R=0;R<(1<<n-m);R++){
		for(int L=0;L<(1<<m);L++){//枚举中间态 LR  
			int sv=v[L].size(),pv=0; pair<int,int> cur=mp(inf,0);
			for(auto super:u[R]){//枚举 R 超集
				int rest=W-sum[super-(R<<m)];
				while(pv<sv&&sum[L-v[L][pv]]<=rest)//双指针匹配 L' 
					upd(cur,dp[v[L][pv++]|(R<<m)]);
				if(cur.first==inf) continue;
				pair<int,int> tmp=cur;
				tmp.fi+=b[maxbit(super)]; upd(dp[L|super],tmp);
			}
		}
	}
	cout<<dp[(1<<n)-1].fi<<" "<<dp[(1<<n)-1].se;
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

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

output:

0 3

result:

wrong answer 1st numbers differ - expected: '9', found: '0'