zoukankan      html  css  js  c++  java
  • 中国象棋 (09 安徽)

    2016-06-01 18:24:32

    题目链接: 中国象棋 (Codevs No.2227)

                    中国象棋 (洛谷 No.2051)

    题目大意:

      在一个N*M的棋盘上放置中国象棋中的炮,求使的放置的炮不能互相攻击的方案总数MOD奇怪的数

    解法:

      一看就是动态规划(QAQ一看就不会)

      看了看题解理解了一下

      DP[i][j][k]表示现在处于i行,其中已有j列是放置了一个炮,有k列是放置了两个炮(那么空的就是M-j-k喽)

      这个状态一共可能有6种来源

        1.没做改变 直接从上一行推来 DP[i][j][k]+=DP[i-1][j][k]

        2.在空列放置了一个 DP[i][j][k]+=DP[i-1][j-1][k]*(M-k-j+1);                    (后面乘的就是空列的个数)

        3.在空列放置了两个并且不重叠 DP[i][j][k]+=DP[i-1][j-2][k]*(M-k-j+2)*(M-k-j+1)/2;     (后面乘的是在M-k-j+2个空列中取两个的组合数)

        4.在放置了一个的列上再放一个 DP[i][j][k]+=DP[i-1][j+1][k-1]*(j+1);                                                    (后面乘的是放了一个的列个数)

        5.在放置了一个的不同两列上再各放一个 DP[i][j][k]+=DP[i-1][j+2][k-2]*(j+2)*(j+1)/2;              (后面是在j+2个放了一个的列中取两个的组合数)

        6.在放置了一个的列和一个空列上各放一个 DP[i][j][k]+=DP[i-1][j][k-1]*(M-k-j+1)*j;                     (这个好好想想吧,j牵扯到两次改变,领会就好)

     1 //中国象棋 (09 安徽)
     2 //动态规划
     3 #include<stdio.h>
     4 #include<algorithm>
     5 using namespace std;
     6 const int MOD=9999973;
     7 const int maxn=110;
     8 long long DP[maxn][maxn][maxn];
     9 int N,M;
    10 long long ans;
    11 int main()
    12 {
    13     scanf("%d %d",&N,&M);
    14     DP[0][0][0]=1;
    15     for(int i=1;i<=N;i++)
    16     {
    17         for(int j=0;j<=M;j++)
    18         {
    19             for(int k=0;k<=M-j;k++)
    20             {
    21                 DP[i][j][k]+=DP[i-1][j][k];
    22                 DP[i][j][k]%=MOD;
    23                 if(j>=1)
    24                 {
    25                     DP[i][j][k]+=DP[i-1][j-1][k]*(M-k-j+1);
    26                     DP[i][j][k]%=MOD;
    27                 }
    28                 if(j>=2)
    29                 {
    30                     DP[i][j][k]+=DP[i-1][j-2][k]*(M-k-j+2)*(M-k-j+1)/2;
    31                     DP[i][j][k]%=MOD;
    32                 }
    33                 if(j>=1&&k>=1)
    34                 {
    35                     DP[i][j][k]+=DP[i-1][j][k-1]*(M-k-j+1)*j;
    36                     DP[i][j][k]%=MOD;
    37                 }
    38                 if(k>=1)
    39                 {
    40                     DP[i][j][k]+=DP[i-1][j+1][k-1]*(j+1);
    41                     DP[i][j][k]%=MOD;
    42                 }
    43                 if(k>=2)
    44                 {
    45                     DP[i][j][k]+=DP[i-1][j+2][k-2]*(j+2)*(j+1)/2;
    46                     DP[i][j][k]%=MOD;
    47                 }
    48             }
    49         }
    50     }
    51     for(int i=0;i<=M;i++)
    52     {
    53         for(int j=0;j<=M-i;j++)
    54         {
    55             ans+=DP[N][i][j];
    56             ans%=MOD;
    57         }
    58     }
    59     printf("%lld",ans);
    60 }
  • 相关阅读:
    【玩转微信公众平台之二】 账号注冊
    SharePoint 2010 Form Authentication (SQL) based on existing database
    淘宝API学习之道:淘宝API相关了解
    Java中Map的使用
    ROADS+dijkstra的灵活运用+POJ
    Jquery Ajax时 error处理 之 parsererror
    P1719 最大加权矩形
    回文串
    P1816 忠诚
    P1725 琪露诺
  • 原文地址:https://www.cnblogs.com/Neptune-/p/5550675.html
Copyright © 2011-2022 走看看