题目中的小数据点(前三个)全过,自己也没拍出问题,大点统一只过第一个和最后一个。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5050,mod=20060723;
int dp[N][N][2],cnt[N],len[N],C[N][N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&len[i]);
sort(len+1,len+n+1);
int ans=0;
C[1][1]=C[1][0]=C[0][0]=1;
for(int i=2;i<=n;i++){
C[i][0]=1;
for(int j=1;j<=i;j++){
C[i][j]=((ll)C[i-1][j-1]+C[i-1][j])%mod;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
ans=((ll)ans+(ll)len[i]*j*C[i-1][j-1]%mod)%mod;
}
}
for(int i=1;i<=n;i++)dp[i][0][1]=dp[i][0][2]=1;
for(int i=1;i<=n;i++){
int tp=0;
for(int j=i-1;j;j--){
while(len[tp+1]+len[j]<=len[i])tp++;
if(tp>=j){
dp[i][j][1]=dp[j][j-1][1];
dp[i][j][2]=((ll)dp[j][j-1][2]+dp[j][j-1][1])%mod;
}
else{
dp[i][j][1]=dp[j][tp][1];
dp[i][j][2]=((ll)dp[j][tp][2]+dp[j][tp][1])%mod;
}
}
for(int j=1;j<i;j++){
dp[i][j][1]=((ll)dp[i][j][1]+dp[i][j-1][1])%mod;
dp[i][j][2]=((ll)dp[i][j][2]+dp[i][j-1][2])%mod;
}
}
for(int i=1;i<=n;i++){
ans=((ll)ans+mod-(ll)dp[i][i-1][2]*len[i]%mod)%mod;
}
printf("%d",ans);
return 0;
}