来自学长馈赠4
考试成绩:Rank 6 250分 再接再厉
提纲:T1:摩尔投票,O(1)空间查找区间众数+计算空间大小
1Mib=1024KB=1024*1024B=1024*1024/4
B=字节
int=4字节
T2:概率期望
T3:预设性DP
t1t2不说了,板子,不犯低错就行
T3:预设型DP
发现A,B是相对位置关系,固定A:1,2,3,4.......n
考虑B的位置:
f[][][]=__结果肯定是方案数(乘法原理的优化)
magic(K)作为一个维度考虑,对于转移来说,我定义当且仅当AB同时有数才计算贡献
考虑前i个位置里有j个有空位的方案数,(一步一步进行,保证我每次放进去的数都具有某种特定的性质(比如一定是区间最大的或最小的))
然后对于1--i的数字可以放在i+1--n位置,空位的概念就可以解决
对于到第i个位置的状态,我放i,1--i-1有j个空位一定有贡献
j个数一定<i,放到i一定是i有贡献
i一定当前是空位
就可以选择i放i,i放j个,j位值放i或者同时
这个就可以从确定的状态转移
int f[55][55][55*55]; //考虑前i个位置,j个空位,magic值是K的方案数 int n,K; int main() { n=re(),K=re(); int mx=min(n*n,K-1); // f[1][0][1]=f[1][1][0]=1; f[0][0][0]=1; _f(i,1,n) { _f(j,0,i) { _f(k,0,mx) { //f[i+1][j+1][k]=((ll)f[i+1][j+1][k]+(ll)f[i][j][k])%MOD; // f[i+1][j][k+i]=(f[i+1][j][k+i]+f[i][j][k]*(2*j+1)) if(j>=1)f[i][j][k]=((ll)f[i][j][k]+(ll)f[i-1][j-1][k])%MOD;//这个位置不放数 if(k>=i) f[i][j][k]=((ll)f[i][j][k]+(ll)f[i-1][j][k-i]*j%MOD)%MOD;//i位置放前j个数字 if(k>=i)f[i][j][k]=((ll)f[i][j][k]+(ll)f[i-1][j][k-i]*j%MOD)%MOD;//j个空位置放i if(k>=i)f[i][j][k]=((ll)f[i][j][k]+(ll)f[i-1][j][k-i]%MOD)%MOD;//i位置放i if(k>=2*i)f[i][j][k]=((ll)f[i][j][k]+(ll)f[i-1][j+1][k-2*i]*(j+1)%MOD*(j+1)%MOD)%MOD;//i位置放前j个数字,前j个空位放i // chu("f[%d][%d][%d]:%d\n",i,j,k,f[i][j][k]); } } } int ans=0;int jc=1; _f(i,0,K-1) ans=((ll)ans+(ll)f[n][0][i])%MOD; _f(i,1,n)jc=(ll)jc*i%MOD; ans=((ll)jc-(ll)ans+MOD)%MOD; _f(i,1,n) { ans=(ll)ans*i%MOD; } chu("%d",ans); return 0; }