題目
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);
}