专栏文章

ARC207A Affinity for Artifacts 题解

AT_arc207_a题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mindme35
此快照首次捕获于
2025/12/02 00:41
3 个月前
此快照最后确认于
2025/12/02 00:41
3 个月前
查看原文
设总成本为 ww,第 ii 个灯是第 pip_i 个被点亮的。考虑每个灯节约了多少成本,则显然有:
(i=1nai)w=i=1nmin(ai,pi1)\left(\sum_{i=1}^n a_i\right)-w=\sum_{i=1}^n \min(a_i,p_i-1)
考虑把 aia_i 看作 11 类数,pi1p_i-1 看作 22 类数,将所有 aia_i 和所有 pi1p_i-1 扔进一个长度为 2n2n 的数列 cc 中并从大到小排序,每次选出一个 11 类数和 22 类数进行匹配,贡献为较小的数的值。
fi,j,kf_{i,j,k} 表示考虑到数列 cc 的第 ii 项,此时一共匹配了 jj 对数,总贡献为 kk 的方案数。转移时,首先根据 i,ji,j 和前缀和数组,计算出未匹配的 11 类数数量 xx 和未匹配的 22 类数数量 yy,再根据 ci+1c_{i+1} 的类型分别处理:
  • ci+1c_{i+1}11 类数:
    • y>0y>0:对 ci+1c_{i+1} 进行匹配,fi+1,j+1,k+ci+1fi+1,j+1,k+ci+1+y×fi,j,kf_{i+1,j+1,k+c_{i+1}} \leftarrow f_{i+1,j+1,k+c_{i+1}}+y \times f_{i,j,k}
    • 不对 ci+1c_{i+1} 进行匹配,fi+1,j,kfi+1,j,k+fi,j,kf_{i+1,j,k} \leftarrow f_{i+1,j,k}+f_{i,j,k}
  • ci+1c_{i+1}22 类数:
    • x>0x>0:对 ci+1c_{i+1} 进行匹配,fi+1,j+1,k+ci+1fi+1,j+1,k+ci+1+x×fi,j,kf_{i+1,j+1,k+c_{i+1}} \leftarrow f_{i+1,j+1,k+c_{i+1}}+x \times f_{i,j,k}
    • 不对 ci+1c_{i+1} 进行匹配,fi+1,j,kfi+1,j,k+fi,j,kf_{i+1,j,k} \leftarrow f_{i+1,j,k}+f_{i,j,k}
初始化 f0,0,0=1f_{0,0,0}=1。设 v=(i=1nai)xv=\left(\sum\limits_{i=1}^n a_i\right)-x,特判一下 v<0v \lt 0v>n(n1)2v \gt \frac {n(n-1)}2 的情况,答案即为 i=vn(n1)2f2n,n,i\sum\limits_{i=v}^{\frac{n(n-1)}{2}} f_{2n,n,i}
时间复杂度 O(n4)\mathcal O(n^4)
C
const int N=105,mod=998244353;
int n,x,a[N],s[N<<1][3],f[N<<1][N][N*(N-1)/2];
ll sum,v;
pii p[N<<1];
int get(int i,int j){
	int a=s[i][1],b=s[i][2];
	return b-a+j;
}
void add(int &a,int b){
	a+=b;
	if(a>=mod) a-=mod;
}
void solve(){
	cin>>n>>x;
	for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i];
	v=sum-x;
	if(v<0) v=0;
	if(v>n*(n-1)/2) v=n*(n-1)/2+1;
	for(int i=1;i<=n;i++) p[i]={a[i],1},p[n+i]={i-1,2};
	sort(p+1,p+n+n+1),reverse(p+1,p+n+n+1);
	for(int i=1;i<=n+n;i++) for(int j=1;j<=2;j++) s[i][j]=s[i-1][j]+(p[i].se==j);
	f[0][0][0]=1;
	for(int i=0;i<n+n;i++){
		for(int j=0;j<=min(s[i][1],s[i][2]);j++){
			int x=s[i][1]-j,y=s[i][2]-j;
			for(int s=0;s<=n*(n-1)/2;s++){
				if(p[i+1].se==1){
					if(y!=0) add(f[i+1][j+1][s+p[i+1].fi],1ll*f[i][j][s]*y%mod);
					add(f[i+1][j][s],f[i][j][s]);
				}
				else{
					if(x!=0) add(f[i+1][j+1][s+p[i+1].fi],1ll*f[i][j][s]*x%mod);
					add(f[i+1][j][s],f[i][j][s]);
				}
			}
		}
	}
	int ans=0;
	for(int i=v;i<=n*(n-1)/2;i++) add(ans,f[n+n][n][i]);
	cout<<ans<<endl;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...