本题我们后推前
设推到位置i,那么【1..i-1]其实已经按顺序排列好了。由于是全排列,我们本次要寻找的数字i,可能的位置有n-i种,我们枚举这n-i+1种位置,对于每一个位置,剩下的数字也是全排列,所以每一个位置就代表了 factor[n-i] 种情况,一旦我们对某个位置这样做了,那么我们排序代价之和就是w[i][j]*factor[n-i]。但是,这仅仅是这一个位置,这一个数的排序代价。每一个位置排序之后,还需要剩下的n-i个数进行排序,故考虑承接前n-i次,即对每一个i每一个位置归位后,还必须都加上dp[i+1],表示承接了将后面数字归位的代价
#include<iostream>
#include<cstring>
#include<cstdio>
# define mod 998244353
using namespace std;
typedef long long int ll;
ll factor[550];
ll dp[550];
ll w[550][550];
int main()
{
factor[1]=1;
for(int i=2;i<=500;i++)
{
factor[i]=(i*factor[i-1])%mod;
}
int n;
cin>>n;
for(int i=1;i<n;i++)
{
for(int j=i;j<=n;j++)
{
scanf("%lld",&w[i][j]);
}
}
for(int i=n-1;i>=1;i--)
{
for(int j=i;j<=n;j++)
{
dp[i]=(dp[i]+dp[i+1]+w[i][j]*factor[n-i])%mod;
}
}
cout<<dp[1];
}