题解:AT_arc207_a [ARC207A] Affinity for Artifacts
light_searcher · · 题解
首先做第一步转化,
把重排看作是
称
这样就可以开始 dp 了。设
假设当前转移到的是
这个转移比较好理解,但是这样是
因为已经匹配了的一类点和二类点的数量总是相同,设
那么把状态稍微改一下,设
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=105,mod=998244353;
int n,x,f[2][N][N*N],ans,sum,cnt[2];
pair<int,int>a[2*N];
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>x;
for(int i=1;i<=n;i++) cin>>a[i].first,sum+=a[i].first,a[n+i]={i-1,1};
sort(a+1,a+n*2+1);
sum-=x;
if(sum>n*(n-1)/2){
cout<<0<<'\n';
return 0;
}
if(sum<0){
ans=1;
for(int i=1;i<=n;i++) ans=ans*i%mod;
cout<<ans<<'\n';
return 0;
}
f[0][0][0]=1;
for(int i=1;i<=2*n;i++){
cnt[a[i].second]++;
memset(f[i&1],0,sizeof(f[i&1]));
int p=i&1,q=p^1;
for(int j=0;j<=n;j++)
for(int k=0;k<=n*(n-1)/2;k++){
if(j) f[p][j][k]=1ll*(cnt[!a[i].second]-j+1)*f[q][j-1][k]%mod;
if(k>=a[i].first) f[p][j][k]=(f[p][j][k]+f[q][j][k-a[i].first])%mod;
}
}
for(int i=sum;i<=n*(n-1)/2;i++) ans=(ans+f[0][n][i])%mod;
cout<<ans<<'\n';
return 0;
}