BZOJ P1801 中国象棋 【递推】

题目分析:

读完题第一反应状态压缩,然后一看数据范围,好像状态压缩只能过一半(反正我没写状态压缩)。这道题最开始也给了我一种容斥原理的感觉,但是完全不可能是容斥原理,然后就想到了递推,想了想递推的思路,看了看数据范围感觉递推可做。但是这个时候我并没有直接写代码而是翻了翻题解验证了我的想法是对的才开始敲。(经常翻题解是不好的习惯)

DP(I,J,K)表示前I行当中每列放了1个炮兵的列数有J列,放了2个炮兵的列数有K列,显然J+K<=M,于是思索一下就可以得到如下的递推关系:
这里写图片描述

其他:
这里写图片描述
这里写图片描述
如果有人上面个递推式不是很懂的话就留一下言我再补充。

关键代码:

for(long long I=1;I<=N;I++){
        for(long long J=0;J<=M;J++){
            for(long long K=0;K+J<=M;K++){
                DP(I,J,K)=DP(I-1,J,K);
                if(J>=1){
                    DP(I,J,K)=(DP(I,J,K)+DP(I-1,J-1,K)*(M-(J-1)-K))%Mod;
                }
                if(K>=1){
                    DP(I,J,K)=(DP(I,J,K)+DP(I-1,J+1,K-1)*(J+1))%Mod;
                }
                if(J>=2){
                    LL P=M-(J-2)-K;
                    DP(I,J,K)=(DP(I,J,K)+DP(I-1,J-2,K)*(P*(P-1)>>1))%Mod;
                }
                if(K>=1){
                    DP(I,J,K)=(DP(I,J,K)+DP(I-1,J,K-1)*(M-(J-1)-K)*J)%Mod;
                }
                if(K>=2){
                    LL P=J+2;
                    DP(I,J,K)=(DP(I,J,K)+DP(I-1,J+2,K-2)*(P*(P-1)>>1))%Mod;
                }
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/yanzhenhuai/article/details/80460778
今日推荐