题目

Description

给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足每行只有一枚棋子,每列只有一枚棋子的限制,求有多少种方案。

Input

第一行一个N,接下来一个N*N的矩阵。N<=200,0表示没有障碍,1表示有障碍,

Output

一个整数,即合法的方案数。

Solution

我们先来科普一下错排问题。

错排问题指考虑一个有n个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排。 n个元素的错排数记为D(n)。 研究一个排列错排个数的问题,叫做错排问题或称为更列问题。  ---《百度百科》

看上去这就是一个递推问题,那么递推式是如何推出来呢?

当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用D(n)表示,那么D(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推.
第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法;
第二步,放编号为k的元素,这时有两种情况:⑴把它放到位置n,那么,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-2个元素就有D(n-2)种方法;⑵第k个元素不把它放到位置n,这时,对于这n-1个元素,有D(n-1)种方法;
综上得到
   D(n) = (n-1) *(D(n-2) + D(n-1))
特殊地,D(1) = 0, D(2) = 1.
 
知道了这个之后,这题就是一个裸的高精了。
Code
// By YoungNeal
#include<cstdio>
using namespace std;
// D(n)=(n-1)*(D(n-1)+D(n-2))
// D(1)=0 D(2)=1 int n;
int D[][]; void ad(int now){
int x=;
for(int i=;i<;i++){
D[now][i]=D[now-][i]+D[now-][i]+x;
x=D[now][i]/;
D[now][i]%=;
}
x=;
for(int i=;i<;i++){
D[now][i]=D[now][i]*(now-)+x;
x=D[now][i]/;
D[now][i]%=;
}
} signed main(){
scanf("%d",&n);
D[][]=;
if(n==||n==){
printf("%d",n-);
return ;
}
for(int i=;i<=n;i++)
ad(i);
int lenc=;
while(D[n][lenc]==) lenc--;
while(lenc) printf("%d",D[n][lenc--]);
return ;
}

[HAOI2016] 放棋子及错排问题的更多相关文章

  1. 洛谷 P3182 [HAOI2016]放棋子(错排问题)

    题面 luogu 题解 裸的错排问题 错排问题 百度百科:\(n\)个有序的元素应有\(n!\)个不同的排列,如若一个排列使得所有的元素不在原来的位置上,则称这个排列为错排:有的叫重排.如,1 2的错 ...

  2. 【BZOJ4563】[Haoi2016]放棋子 错排+高精度

    [BZOJ4563][Haoi2016]放棋子 Description 给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在这个矩阵上放N枚棋子(障碍 ...

  3. bzoj4563: [Haoi2016]放棋子(错排+高精)

    4563: [Haoi2016]放棋子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 387  Solved: 247[Submit][Status] ...

  4. 洛谷P3182 [HAOI2016]放棋子

    P3182 [HAOI2016]放棋子 题目描述 给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在这个矩阵上放N枚棋子(障碍的位置不能放棋子),要 ...

  5. [Haoi2016]放棋子 题解

    4563: [Haoi2016]放棋子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 440  Solved: 285[Submit][Status] ...

  6. 洛谷 P3182 [HAOI2016]放棋子(高精度,错排问题)

    传送门 解题思路 不会错排问题的请移步——错排问题 && 洛谷 P1595 信封问题 这一道题其实就是求对于每一行的每一个棋子都放在没有障碍的地方的方案数. 因为障碍是每行.每列只有一 ...

  7. BZOJ4563:[HAOI2016]放棋子——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4563 给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列 ...

  8. BZOJ 4563: [Haoi2016]放棋子

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 389  Solved: 248[Submit][Status][Discuss] Descriptio ...

  9. BZOJ——T 4563: [Haoi2016]放棋子

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 387  Solved: 247[Submit][Status][Discuss] Descriptio ...

随机推荐

  1. R语言︱贝叶斯网络语言实现及与朴素贝叶斯区别(笔记)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 一.贝叶斯网络与朴素贝叶斯的区别 朴素贝叶斯的 ...

  2. javascript 获取滚动条距离顶部的位置(兼容所有的)。

    function getScrollTop() { var scrollPos; if (window.pageYOffset) { scrollPos = window.pageYOffset; } ...

  3. dojo柱形图

    dojo柱形图添加属性 1.给柱状图的柱子填充颜色 .addSeries("A",[45,56,12,23,78,67],{stroke:{color:"#FF0000& ...

  4. code is 9998;desc is 插入失败exception is org.hibernate.exception.JDBCConnectionException: Could not op

    1.错误描述 [ERROR:]2015-05-05 09:27:12,090 [插入失败] org.hibernate.exception.JDBCConnectionException: Could ...

  5. (十六)java中的String

    String:字符串类型,是java中最常用的引用类型,String是不可变的,java.lang.String是由final修饰,此类不可被继承.     String是不可变的,指的是字符串一旦创 ...

  6. Python中re模块的使用

    #table-1 thead,#table-1 tr { border-top-width: 1px; border-top-style: solid; border-top-color: rgb(2 ...

  7. SpringMVC工作流程描述

    向服务器发送HTTP请求,请求被前端控制器 DispatcherServlet 捕获. DispatcherServlet 根据 <servlet-name>-servlet.xml 中的 ...

  8. 消息队列mq的原理及实现方法

    消息队列技术是分布式应用间交换信息的一种技术.消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走.通过消息队列,应用程序可独立地执行--它们不需要知道彼此的位置.或在继续执行前不需要等待 ...

  9. 关于protected关键字

    protected,算是默认的访问作用域的超集,他们在相同包下时,都可以访问所声明的成员:但对于不同包的访问,默认访问域就不行,protected也必须是通过继承关系来访问. TestBase bas ...

  10. javascript右键菜单分析

    右键菜单 思路 1.遮蔽原来的默认右键菜单 2.新建右键菜单跟随鼠标移动 3.注意边界处的位置变化 4.自定义右键内容的具体效果 具体 这样的事件涉及到有关contextmenu事件,阻止默认事件,获 ...