来自学长馈赠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;
}

 

 

 

 

posted on 2022-07-24 18:57  HZOI-曹蓉  阅读(31)  评论(0编辑  收藏  举报