zoukankan      html  css  js  c++  java
  • P2051 [AHOI2009]中国象棋(动态规划)

    思路

    好像是一道挺水的计数的,不知道为什么会是紫题

    显然每行和每列最多放两个

    首先考虑状压,然后发现三进制状压可做,但是三进制太麻烦了,可以拆成两个二进制,一个表示该列是否是放了一个的,一个表示该列是否是放了两个的

    可以发现并不需要知道具体每列放了什么,只需要知道有几个即可,所以把有几列放了一个和有几列放了两个表示进状态中,滚动数组优化一下空间即可

    状态转移在代码中

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int MOD = 9999973;
    int m,n,cur;
    int dp[2][110][110];
    int C(int n){
        return (1LL*n*(n-1)/2)%MOD;
    }
    int main(){
        scanf("%d %d",&n,&m);
        dp[cur][0][0]=1;
        for(int i=0;i<=n-1;i++,cur^=1){
            memset(dp[cur^1],0,sizeof(dp[cur^1]));
            for(int j=0;j<=m;j++)
                for(int k=0;k<=m-j;k++){
                    dp[cur^1][j][k]=(dp[cur][j][k]+dp[cur^1][j][k])%MOD;//不放
                    if(j+k+1<=m)
                        dp[cur^1][j+1][k]=(dp[cur^1][j+1][k]%MOD+1LL*dp[cur][j][k]*(m-k-j)%MOD)%MOD;//放一个在没有的列上
                    if(j>=1)
                        dp[cur^1][j-1][k+1]=(dp[cur^1][j-1][k+1]%MOD+1LL*dp[cur][j][k]*j%MOD)%MOD;//放一个在有一个的列上
                    if(j+2+k<=m)
                        dp[cur^1][j+2][k]=(dp[cur^1][j+2][k]%MOD+1LL*dp[cur][j][k]*C(m-j-k)%MOD)%MOD;//放两个在没有的列上
                    if(j>=2)
                        dp[cur^1][j-2][k+2]=(dp[cur^1][j-2][k+2]%MOD+1LL*dp[cur][j][k]*C(j)%MOD)%MOD;//放两个在有一个的列上
                    if(j+k+1<=m&&j>=1)
                        dp[cur^1][j][k+1]=(dp[cur^1][j][k+1]%MOD+1LL*dp[cur][j][k]%MOD*(m-j-k)%MOD*j%MOD)%MOD;//放一个在没有的列上,一个在有的列上
                }
        }
        int ans=0;
        for(int j=0;j<=m;j++)
            for(int k=0;k<=m-j;k++){
                ans=(ans+dp[cur][j][k])%MOD;
            }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    WPF学习之路(八)页面
    面试题整理:C#(一)
    [转载] Tomcat架构分析
    [转载] ConcurrentHashMap原理分析
    [转载] Java并发编程:Lock
    [转载] KAFKA分布式消息系统
    [转载] Java并发编程:Callable、Future和FutureTask
    [转载] Java线程池框架源码分析
    [转载] 红黑树(Red Black Tree)- 对于 JDK TreeMap的实现
    [转载] RED-BLACK(红黑)树的实现TreeMap源码阅读
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10123661.html
Copyright © 2011-2022 走看看