BZOJ1087=Codevs2451=洛谷P1896&P2326互不侵犯
1087: [SCOI2005]互不侵犯King
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2885 Solved: 1693
[Submit][Status][Discuss]
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上
左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
Sample Output
HINT
Source
一开始的时候,使劲往规律方面靠,20分钟过去了,没发现什么通用规律
于是就暴力写搜索(建议用bfs写,略快),写完一看,数据这么小,记忆化?还是直接list吧。
打了一个小时的表。终于功夫不负有心人啊,AC了。
附AC代码<打表代码>(民间版):
- #include<bits/stdc++.h>
- using namespace std;//规律:k>((n+1)/2)^2 必为0
- long long ys[10][82]={{0LL},
- {1LL,1LL},
- {1LL,4LL},
- {1LL,9LL,16LL,8LL,1LL},
- {1LL,16LL,78LL,140LL,79LL},
- {1LL,25LL,228LL,964LL,1987LL,1974LL,978LL,242LL,27LL,1LL},
- {1LL,36LL,520LL,3920LL,16834LL,42368LL,62266LL,51504LL,21792LL,3600LL},
- {1LL,49LL,1020LL,11860LL,85275LL,397014LL,1220298LL,2484382LL,3324193LL,2882737LL,1601292LL,569818LL,129657LL,18389LL,1520LL,64LL,1LL},
- {1LL,64LL,1806LL,29708LL,317471LL,2326320LL,12033330LL,44601420LL,119138166LL,229095676LL,314949564LL,305560392LL,204883338LL,91802548LL,25952226LL,4142000LL,281571LL},
- {1LL,81LL,2968LL,65240LL,962089LL,10087628LL,77784658LL,450193818LL,1979541332LL,6655170642LL,12848094442LL,29492596820LL,46439242830LL,57647295377LL,49138545860LL,31122500764LL,14518795348LL,4959383037LL,1237072414LL,224463798LL,29275410LL,2673322LL,163088LL,6150LL,125LL,1}};
- int main(){
- int n,k;
- cin>>n>>k;
- cout<<ys[n][k];
- return 0;
- }
下面我为大家手抄了一遍网上的正解(所谓的状压dp)
AC代码+题解(官方版):
- //dfs预处理+状压dp:将2^9-1种状态压缩为m种可行状态,循环次数大大减少
- #include<cstdio>
- using namespace std;
- #define N 100
- long long int f[N][N][600],ans;//f[i][j][k]=放棋子到第i行,且已经放了j个棋子,此时第i行状态为k的方案数,ans=最终方案数
- int stay[N];//stay[i]=第i种可行状态
- int map[N][N],cnt[N];//cnt[i]=第i种状态对应棋子数
- int n,k,m=0;
- void pre_dfs(int x,int pos,int now){//dfs预处理枚举出同一行内互不冲突的状态,x是已经放了的棋子数,n是当前放棋子的位置,now=当前行状态
- int i;
- stay[++m]=now;//新增一种可行状态
- cnt[m]=x;
- if(x>=(n+1)/2||x>=k) return;//如果已经放的棋子数超过格子半数,明显不能再放了,退出
- for(i=pos+2;i<=n;i++) pre_dfs(x+1,i,now+(1<<(i-1))); //枚举下一颗棋子放的位置
- }
- void pre_map(){
- int i,j;
- for(i=1;i<=m;i++){//第一行状态
- for(j=1;j<=m;j++){//第二行状态
- map[i][j]=map[j][i]=((stay[i]&stay[j])||((stay[i]>>1)&stay[j])||((stay[i]<<1)&stay[j]))?0:1; //当第一行某个点和第二行某个点在对角线或同一列时,两行冲突了
- }
- }
- for(i=1;i<=m;i++) f[1][cnt[i]][i]=1;//dp预处理
- }
- int main(){
- scanf("%d%d",&n,&k);
- pre_dfs(0,-1,0); //预处理枚举出同一行所有可行方案,减少DP循环次数
- pre_map(); //预处理上下左右冲突的情况以及dp初始化
- for(int i=2;i<=n;i++){//i行
- for(int j=0;j<=k;j++){//j个棋子
- for(int now=1;now<=m;now++){
- if(cnt[now]>j) continue; //当前已放的棋子数比这一行状态对应棋子数少,显然不符合题意,跳过
- for(int h=1;h<=m;h++) //枚举上一行状态
- if(map[h][now]&&cnt[h]+cnt[now]<=j) f[i][j][now]+=f[i-1][j-cnt[now]][h]; //符合条件,加上上一行的可行方案数
- }
- }
- }
- for(int i=1;i<=m;i++)ans+=f[n][k][i]; //统计答案
- printf("%lld\n",ans);
- return 0;
- }
BZOJ1087=Codevs2451=洛谷P1896&P2326互不侵犯的更多相关文章
- 洛谷 P1896 [SCOI2005]互不侵犯
洛谷 P1896 [SCOI2005]互不侵犯 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8 ...
- 【题解】洛谷P1896 [SCOI2005] 互不侵犯(状压DP)
洛谷P1896:https://www.luogu.org/problemnew/show/P1896 前言 这是一道状压DP的经典题 原来已经做过了 但是快要NOIP 复习一波 关于一些位运算的知识 ...
- 洛谷P1896 [SCOI2005]互不侵犯King
P1896 [SCOI2005]互不侵犯King 题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共 ...
- 洛谷——P1896 [SCOI2005]互不侵犯
P1896 [SCOI2005]互不侵犯 状压DP入门题 状压DP一般需要与处理状态是否合法,节省时间 设定状态dp[i][j][k]表示第i行第j个状态选择国王数为k的方案数 $dp[i][j][n ...
- 洛谷 P1896 [SCOI2005]互不侵犯 (状态压缩DP)
题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 注:数据有加强(2018/4/25) ...
- 洛谷 P1896 [SCOI2005]互不侵犯King
题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入输出格式 输入格式: 只有一行,包 ...
- 洛谷P1896 [SCOI2005]互不侵犯King【状压DP】
题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入格式: 只有一行,包含两个数N,K ...
- 【洛谷P1896】互不侵犯
题目大意:给定 N*N 的棋盘,一共放 K 个国王,一共有多少种方法. 题解: i&i<<1 判断是否每个 1 的位置之间都有 0. i&j<<1 判断 i 中 ...
- 洛谷P1896||bzoj1087 [SCOI2005]互不侵犯
bzoj1087 洛谷P1896 想了很久,太久没做状压都已经不会了... 状压每一行就好了 #include<cstdio> #include<algorithm> #inc ...
随机推荐
- ArrayList练习之存储自定义对象并遍历
新建一个Student.java类 Student.java /* * 这是一个学生类 */ public class Student { private String name; private i ...
- MyBatis 3 分页
利用MyBatis 3进行分页,选定的数据库表c_province,有3列,id列,provinceid列,province列,用Oracle数据库.首先建立一个对应的实体类,Province有3个属 ...
- mysql汉字转拼音函数
-- 创建汉字拼音对照临时表 CREATE TABLE IF NOT EXISTS `t_base_pinyin` ( `pin_yin_` ) CHARACTER SET gbk NOT NULL, ...
- 【java基础 4】树形结构数据呈现的非递归算法(循环)实现
一.基本概况 上一篇博客介绍到用递归实现树结构数据的查找,那么这篇博客,我就结合自己对于树的理解,然后用一种非递归的方式进行树结构数据的处理.首先,改造数据库表设计,加入度的概念: 首先,layer的 ...
- HDU-2159 FATE,01背包变形
FATE 这道题和完全背包十分类似,只不过加上了忍耐度这个条件限制,所以很正常的想到用三维数组来模拟.但背包问题优化只有一层循环,这里当然也可以把种类这一层省略.d[i][j]表示杀i只怪耗费忍耐度为 ...
- POJ 3248 Catch That Cow
http://poj.org/problem?id=3278 二维BFS #include <iostream> #include <stdio.h> #include < ...
- 2017"百度之星"程序设计大赛 - 初赛(B)度度熊的交易计划
n个村庄m条带权路,权值为花费,村庄可以造东西卖东西,造完东西可以换地方卖,给出每个村庄造东西花费a和最多个数b.卖东西价值c和最多个数d,求最大收益. 裸的费用流.然而还WA了一发.很好. 建源向每 ...
- hihoCoder #1067 : 最近公共祖先·二 [ 离线LCA tarjan ]
传送门: #1067 : 最近公共祖先·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho用非常拙劣——或者说粗糙的手段山寨出了一个神奇的网站 ...
- PHP的资源类型
PHP的资源类型 php的资源类型 常见的有:打开文件.数据库连接.图形画布等. 常用操作:创建.使用.释放. 以文件操作为示例: //文件路径 $file_url = './data.txt'; / ...
- Swift 入门学习一:简单值
1.简单值 使用“let”来声明常量,使用“var”来声明变量. 常量,在编译的时候,并不需要有明确的值,但是只能赋值一次.即:可以用常量来表示这样一个值--只需要决定一次,但是需要使用很多次. va ...