【JZOJ 省選模擬】6699. 這鉢和餐廳配合的不是很好

題目

Description
在這裏插入圖片描述

Input
第⼀⾏⼀個n ,代表菜的個數。

接下來⼀⾏ n個正整數 ,代表第 i個菜的下飯度。

Output
⼀⾏⼀個數表⽰所有的上菜順序,它們的下飯度之和對998244353取模的結果。

Sample Input
輸⼊樣例1:
3
1 2 2

輸⼊樣例2:
5
11 63 7 15 26

輸⼊樣例3:
15
2 2 1 2 1 1 2 2 1 2 1 2 2 2 1

Sample Output
輸出樣例1:
765320671

輸出樣例2:
19890604

輸出樣例3:
272794731

Data Constraint
對於所有數據, 1<=n<=200,1<=ai <=1000;

Hint
在這裏插入圖片描述

思路

在這裏插入圖片描述

代碼

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=207,M=N*1007,mod=998244353;
int n;
ll ans,invA=1,sum[N],a[N],inv[M],pre[M],f[M],g[M];
ll power(ll x,ll t)
{
	ll b=1;
	while(t)
	{
		if(t&1) b=b*x%mod;
		x=x*x%mod; t>>=1;
	}
	return b;
}
int main()
{
	freopen("restaurant.in","r",stdin); freopen("restaurant.out","w",stdout);
	scanf("%d",&n);
	for(int i=1; i<=n; i++) scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i],invA=invA*a[i]%mod;
	invA=power(invA,mod-2);
	inv[0]=inv[1]=1; 
	for(int i=2; i<=sum[n]; i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
	pre[0]=1;
	for(int i=1; i<=n; i++) for(int j=sum[i-1]; j>=0; j--) pre[j+a[i]]=(pre[j+a[i]]-pre[j]+mod)%mod;
	for(int i=1; i<=n; i++)
	{
		memset(f,0,sizeof(f));
		for(int j=0; j<=sum[n]; j++) g[j]=pre[j];
		for(int j=sum[n]; j>=a[i]; j--) f[j-a[i]]=(f[j-a[i]]-g[j]+mod)%mod,g[j-a[i]]=(g[j-a[i]]+g[j])%mod;
		for(int j=0; j<=sum[n]; j++) ans=(ans+f[j]*a[i]%mod*a[i]%mod*invA%mod*inv[j+a[i]]%mod)%mod;
	}
	printf("%lld",ans);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章