[CSP-S Simulation Test]: Cicada and sorting (probability DP)

Topic Portal (internal title 93)


Input Format

  A first line integer $ n $, length represents the number of columns.
  The next line number $ n-$ $ a_i $, separated by spaces.


Output Format

  $ $ N-output line number indicates the number of columns on the original position after performing the desired position, note that the expected value of the output at $ \ mod 998244353 $ results.


Data range and tips

$n\leqslant 500,1\leqslant a_i\leqslant 10^3$


answer

Consider $ DP $, provided $ dp [i] [j] [k] $ represent the original $ j $ ranking in the first layer is now $ i $ $ k $ is the probability of metastasis was found or not.

Then set $ g [i] [j] $ denotes merge two pointers point to the sorting process I $, $ J probability of obtaining the first $ G $ array, and then transferred to.

Prove time complexity, found on each floor is actually a convolution, then the complexity of $ T (n) = n ^ 2 + 2T (\ frac {n} {2}) $, according to the main theorem of each layer time complexity is $ T (n) = n ^ 2 $. Therefore, the time complexity of processing a single number is $ \ Theta (n ^ 2) $, since each operand to be processed, then the time complexity is $ \ Theta (n ^ 3) $.

Time complexity: $ \ Theta (n ^ 3) $.

Expectations score: $ 100 $ points.

Actual score: $ 100 $ points.


Code time

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
const int two=499122177;
int n;
int a[501];
long long f[501][501][501],g[501][501],ans;
void merge_sort(int x,int l,int r)
{
	if(l==r){f[x][l][l]=1;return;}
	int mid=(l+r)>>1;
	merge_sort(x+1,l,mid);
	merge_sort(x+1,mid+1,r);
	memset(g,0,sizeof(g));
	g[0][0]=1;
	for(int i=0;i<=mid-l+1;i++)
		for(int j=0;j<=r-mid;j++)
		{
			if(i==mid-l+1)g[i][j+1]=(g[i][j+1]+g[i][j])%mod;
			else if(j==r-mid)g[i+1][j]=(g[i+1][j]+g[i][j])%mod;
			else if(a[i+l]<a[j+mid+1])g[i+1][j]=(g[i+1][j]+g[i][j])%mod;
			else if(a[i+l]>a[j+mid+1])g[i][j+1]=(g[i][j+1]+g[i][j])%mod;
			else
			{
				g[i+1][j]=(g[i+1][j]+g[i][j]*two%mod)%mod;
				g[i][j+1]=(g[i][j+1]+g[i][j]*two%mod)%mod;
			}
		}
	for(int i=l;i<=r;i++)
		for(int j=0;j<=mid-l+1;j++)
			for(int k=0;k<=r-mid;k++)
			{
				if(j==mid-l+1&&k==r-mid)continue;
				if(j==mid-l+1)f[x][i][j+k+l]=(f[x][i][j+k+l]+f[x+1][i][k+mid+1]*g[j][k]%mod)%mod;
				else if(k==r-mid)f[x][i][j+k+l]=(f[x][i][j+k+l]+f[x+1][i][j+l]*g[j][k]%mod)%mod;
				else if(a[j+l]<a[k+mid+1])f[x][i][j+k+l]=(f[x][i][j+k+l]+f[x+1][i][j+l]*g[j][k]%mod)%mod;
				else if(a[j+l]>a[k+mid+1])f[x][i][j+k+l]=(f[x][i][j+k+l]+f[x+1][i][k+mid+1]*g[j][k]%mod)%mod;
				else
				{
					f[x][i][j+k+l]=(f[x][i][j+k+l]+f[x+1][i][k+mid+1]*g[j][k]%mod*two%mod)%mod;
					f[x][i][j+k+l]=(f[x][i][j+k+l]+f[x+1][i][j+l]*g[j][k]%mod*two%mod)%mod;
				}
			}
	sort(a+l,a+r+1);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	merge_sort(1,1,n);
	for(int i=1;i<=n;i++)
	{
		ans=0;
		for(int j=1;j<=n;j++)
			ans=(ans+f[1][i][j]*j)%mod;
		printf("%lld ",ans);
	}
	return 0;
}

rp ++

Guess you like

Origin www.cnblogs.com/wzc521/p/11754395.html