zoukankan      html  css  js  c++  java
  • [BZOJ1801][AHOI2009]中国象棋(递推)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1801

    分析:

    只会50的状态压缩……

    然后搜了下题解,发现是dp

    首先易得每行每列至多有2个棋子

    设f[i][j][k]表示前i行中有j列放了1个棋子,有k列放了2个棋子,那么就有m-j-k列没有放棋子

    那么下面考虑第i行放棋子情况和前i-1行放棋子状态的关系:

    1、如果第i行不放棋子:f[i][j][k]+=f[i-1][j][k]

    2、如果第i行放1个棋子

      ①该棋子放在之前没有放棋子的某一空列上:f[i][j][k]+=f[i-1][j-1][k]*(m-(j-1)-k)

      ②该棋子放在之前放了1个棋子的某一列上:f[i][j][k]+=f[i-1][j+1][k-1]*(j+1)

    3、如果第i行放2个棋子

      ①2个棋子都放在之前没有放棋子的空列上:f[i][j][k]+=f[i-1][j-2][k]*C(m-(j-2)-k,2)

      ②2个棋子都放在之前放过1个棋子的列上:f[i][j][k]+=f[i-1][j+2][k-2]*C(j+2,2)

      ③2个棋子中1个放在空列上,另一个放在之前放过1个棋子的列上:f[i][j][k]+=f[i-1][j][k-1]*(m-j-(k-1))*j;

    然后考虑一下每种情况的条件对上面进行求和就可以。不要忘记了取模

    [反思]很容易想到状态压缩,但是仔细想一想”哪一列是什么状态“对结果并不影响,结果只与”有多少列是什么状态“有关,所以状态压缩大可不必,直接dp即可

  • 相关阅读:
    各种知识点
    链表
    滑动窗口
    数组

    【转】无重复字符的最长子串
    【转】荷兰国旗问题 三指针排序
    【转】回溯思想团灭排列、组合、子集问题
    【LeetCode】45. 跳跃游戏 II
    动态分配内存初始化二维数组
  • 原文地址:https://www.cnblogs.com/wmrv587/p/4138953.html
Copyright © 2011-2022 走看看