【HAOI2016】放旗子
终于自己推出来一道题了quq然而时间有点久,考场上并不大丈夫……
原题:
给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足每行只有一枚棋子,每列只有一枚棋子的限制,求有多少种方案。
N<=200
棋盘放置,这个跟组合数学有点关系(应该没有),N<=200,看上去可以DP(应该不能)
然后我在想组合数学和DP的时候首先发现了两点特殊性:
棋盘的每一行是可以随便换的,因为每行每列互不干扰(产生限制的是棋子),所以可以把所有n相等的情况都看做一种,也就是说题目中给出的棋盘并没有什么卵用(其实如果写20的dfs或60的壮鸭还是要用的
为了方便研究,现在约定每个棋盘上被限制的位置都是从坐上到右下,比如n==4的时候就是酱紫:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
然后如果安行选的话,第i行第j列选完之后,就可以看做把第i行和第j列删掉了
比如上面的n==4的情况,如果删掉第1行第2列,这个方阵就会变成下面酱紫:
0 0 0
0 1 0
0 0 1
多手玩几组数据后容易发现,上面删除后的矩阵有非常亦可赛艇的特点
这是一个3*3的棋盘,并且从(2,2)到(3,3)和2*2的棋盘是一样的(在开始的时候就约定了把所有n相等的情况都看做一种
所以这也可以看成3*3的左上角变成0
接下来在第一行放棋子有两种选择,要么不在(1,1)放,方案数等于3*3的,在(1,1)放,就可以把第一行和第一列删掉,剩下的棋盘就是个2*2的,也就是说在(1,1)放的方案数等于2*2的
所以上面这个被删过的矩阵的方案数就是2*2的方案数+3*3的方案数
因为这个被拿来举例的矩阵是删掉(1,2)的结果,同样也可以删掉(1,2~n),共有n-1种删法,易证每种删法都符合上面的性质
这样就得到了一个关于n*n棋盘方案数的正确表示,可以发现n*n棋盘的方案数只与(n-1)*(n-1)的方案数和(n-2)*(n-2)的方案数有关,这些都是在n之前的量(这话有点奇怪,可以忽略
所以就可以列出递推式,用f[i]表示i*i棋盘的方案数,f[i]=(f[i-1]+f[i-2])*(i-1),初始状态为f[1]=0,f[2]=1
然后这道题就完结了,出题人为了不让推出递推式的同学瞬间秒掉这道题,增加代码复杂度,答案没有膜数,需要高精度
然而可以发现递推式中只有高精加高精和高精乘单精,也不怎么难写(就算是这样,高精度还是有不少细节需要注意
我是偶然发现了两个特殊性才想出这道题,虽然这次依旧没有想起来去往题目特殊性的方面去思考,但是再次证明了想题主要思考特殊性而不是一般性
总之这道题就是发现特殊性(不是太难看出来),往递推的方面思考(思路不要歪到组合数上去),高精度别写挂(注意对拍)就可以拿到满分辣
(然而在考场上我还是想不出来quq
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int dalao=;
void splay(int &x){int mk=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mk=-; ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-''; ch=getchar();}
x=;
}
int n;
int f[][],l[];
int a[];
int main(){//freopen("ddd.in","r",stdin);
cin>>n;
int root;
//for(int i=1;i<=n;++i)for(int j=1;j<=n;++j) splay(root);
f[][]=,l[]=l[]=;
for(int i=;i<=n;++i){
/*l[i]=l[i-1]+l[i-2]-1;
for(int j=1;j<=l[i-1];++j)
for(int k=1;k<=l[i-2];++k){
f[i][j+k-1]+=f[i-1][j]*f[i-2][k];
f[i][j+k]+=f[i][j+k-1]/dalao,f[i][j+k-1]%=dalao;
}*/
l[i]=max(l[i-],l[i-]);
for(int j=;j<=l[i];++j){
f[i][j]+=f[i-][j]+f[i-][j];
f[i][j+]+=f[i][j]/dalao,f[i][j]%=dalao;
}
while(f[i][l[i]+]) ++l[i],f[i][l[i]+]+=f[i][l[i]]/dalao,f[i][l[i]]%=dalao;
for(int j=;j<=l[i];++j) a[j]=f[i][j],f[i][j]=;
for(int j=;j<=l[i];++j){
f[i][j]+=a[j]*(i-);
f[i][j+]+=f[i][j]/dalao,f[i][j]%=dalao;
}
while(f[i][l[i]+]) ++l[i],f[i][l[i]+]+=f[i][l[i]]/dalao,f[i][l[i]]%=dalao;
}
cout<<f[n][l[n]];
for(int i=l[n]-;i>=;--i) printf("%04d",f[n][i]);
cout<<endl;
return ;
}
【HAOI2016】放旗子的更多相关文章
- bzoj4563 HAOI2016放旗子
bzoj传送门 已知了"任意两个障碍不在同一行,任意两个障碍不在同一列",如果我们按每列只能放一个来考虑,那么这\(n\)个障碍一定是一个排列,那么也就是"每一列只能放一 ...
- 【BZOJ4563】[Haoi2016]放棋子 错排+高精度
[BZOJ4563][Haoi2016]放棋子 Description 给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在这个矩阵上放N枚棋子(障碍 ...
- 洛谷P3182 [HAOI2016]放棋子
P3182 [HAOI2016]放棋子 题目描述 给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在这个矩阵上放N枚棋子(障碍的位置不能放棋子),要 ...
- bzoj4563: [Haoi2016]放棋子(错排+高精)
4563: [Haoi2016]放棋子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 387 Solved: 247[Submit][Status] ...
- [Haoi2016]放棋子 题解
4563: [Haoi2016]放棋子 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 440 Solved: 285[Submit][Status] ...
- BZOJ4563: [Haoi2016]放棋子
Description 给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在 这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足每行 ...
- [HAOI2016] 放棋子及错排问题
题目 Description 给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列,要求你在这个矩阵上放N枚棋子(障碍的位置不能放棋子),要求你放N个棋子也满足 ...
- BZOJ4563:[HAOI2016]放棋子——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4563 给你一个N*N的矩阵,每行有一个障碍,数据保证任意两个障碍不在同一行,任意两个障碍不在同一列 ...
- BZOJ 4563: [Haoi2016]放棋子
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 389 Solved: 248[Submit][Status][Discuss] Descriptio ...
随机推荐
- mysql不会使用索引,导致全表扫描情况
不会使用索引,导致全表扫描情况 1.不要使用in操作符,这样数据库会进行全表扫描,推荐方案:在业务密集的SQL当中尽量不采用IN操作符 2.not in 使用not in也不会走索引推荐方案:用not ...
- IDE 版本
BDS 5 2007 D11 VER180 and VER185 RAD Studio 8 XE D15 VER 220 RAD 18 XE 10.1 Berlin D24 VER310 St ...
- RabbitMQ 均衡调度(公平分发机制)
均衡调度是针对Consumer来说的.现在有两个Consumer请求同一个队列的消息.RabbitMQ会将序号为奇数的消息发给第一个Consumer,会将序号为偶数的消息发送给第二个Consumer. ...
- error MSB8008: 指定的平台工具集(V120)未安装或无效。
打开项目属性->配置属性->右面,平台工作集,选为v10 如下图
- SQL-8 找出所有员工当前(to_date='9999-01-01')具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示
题目描述 找出所有员工当前(to_date='9999-01-01')具体的薪水salary情况,对于相同的薪水只显示一次,并按照逆序显示CREATE TABLE `salaries` (`emp_n ...
- redis 解析配置文件
在redis安装文件夹里面有redis.conf,查看配置. 一:基础配置介绍 1.units(单位) --这里可以看到 1k和1kb是不一样的, units 这里单位是不区分大小写的,are al ...
- Java基础学习-Collection
package Collection; import java.util.ArrayList; import java.util.Scanner; /*集合类的特点: * 大小可变 * * Array ...
- webstorm安装流程
第一步:双击安装目录 修改安装目录 尽量不要放在C盘 第二步: 把汉化包 直接复制文件到WebStorm安装目录中lib文件夹中即可,重新打开WebStorm就可以了
- python 元组攻略
1.元组中只包含一个元素时,需要在元素后面添加逗号来消除歧义 tup1=(50,) 2.元组中的元素值使不允许修改的,但可以对元组进行连接组合复制代码 1 tup1=(12,34.56)2 tup2= ...
- 分类算法的R语言实现案例
最近在读<R语言与网站分析>,书中对分类.聚类算法的讲解通俗易懂,和数据挖掘理论一起看的话,有很好的参照效果. 然而,这么好的讲解,作者居然没提供对应的数据集.手痒之余,我自己动手整理了一 ...