QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#779264 | #8005. Crossing the Border | Mirasycle | WA | 0ms | 7684kb | C++14 | 2.2kb | 2024-11-24 18:05:46 | 2024-11-24 18:05:49 |
Judging History
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'