POJ 1321 棋盘问题(DFS & 状压DP)
用DFS写当然很简单了,8!的复杂度,16MS搞定。
在Discuss里看到有同学用状态压缩DP来写,就学习了一下,果然很精妙呀。
状态转移分两种,当前行不加棋子,和加棋子。dp[i][j]中,i代表行数,j代表当前行棋子的状态。j的二进制中,1代表有旗子,0代表无棋子。
贴代码~状压DP果然快一点。
#include <cstdio>
#include <cstring> int n,k,count;
bool mp[][];
int num[];
int dp[][]; int main()
{
// freopen("in.txt","r",stdin); for(int i=;i<;i++)
{
int tmp=i;
while(tmp)
{
if(tmp&)
num[i]++;
tmp>>=;
}
} while(~scanf("%d%d",&n,&k) && n!=- && k!=-)
{
char str[];
for(int i=;i<=n;i++)
{
scanf("%s",str+);
for(int l=;l<=n;l++)
{
if(str[l]=='#')
mp[i][l]=true;
else
mp[i][l]=false;
}
} int status=<<n; memset(dp,,sizeof(dp));
dp[][]=;
for(int i=;i<=n;i++)
{
for(int j=;j<status;j++) if(num[j]<=k)
{
dp[i][j]+=dp[i-][j];
for(int l=;l<=n;l++) if(mp[i][l] && (j&(<<(l-)))==)
{
dp[i][(j|(<<(l-)))]+=dp[i-][j];
}
}
} int ans=;
for(int i=;i<status;i++) if(num[i]==k)
ans+=dp[n][i]; printf("%d\n",ans);
}
}
还有传统的DFS……
#include <cstdio>
#include <cstring> int n,k,count;
bool mp[][];
bool col[]; void DFS(int x,int rest)
{
if(rest==)
{
count++;
return;
}
if(x>n)
return;
for(int i=;i<=n;i++) if(!col[i] && mp[x][i])
{
col[i]=true;
DFS(x+,rest-);
col[i]=false;
}
if(rest+x<=n)
DFS(x+,rest);
} int main()
{
// freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&k) && n!=- && k!=-)
{
memset(col,,sizeof(col));
char str[];
for(int i=;i<=n;i++)
{
scanf("%s",str+);
for(int k=;k<=n;k++)
{
if(str[k]=='#')
mp[i][k]=true;
else
mp[i][k]=false;
}
} count=;
DFS(,k);
printf("%d\n",count);
}
}
POJ 1321 棋盘问题(DFS & 状压DP)的更多相关文章
- POJ 1321 棋盘问题 --- DFS
POJ 1321 题目大意:给定一棋盘,在其棋盘区域放置棋子,需保证每行每列都只有一颗棋子. (注意 .不可放 #可放) 解题思路:利用DFS,从第一行开始依次往下遍历,列是否已经放置棋子用一个数组标 ...
- poj 3254 Corn Fields (状压dp)(棋盘dp)
状压dp入门题 因为当前行的状态只和上一行有关 所以可以一行一行来做 因为m <= 12所以可以用二进制来表示放了或者没有放 0表示没放,1表示放 f[i][state]表示第i行状态为stat ...
- POJ 2411 Mondriaan's Dream ——状压DP 插头DP
[题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...
- poj 2288 Islands and Bridges ——状压DP
题目:http://poj.org/problem?id=2288 状压挺明显的: 一开始写了(记忆化)搜索,但一直T: #include<iostream> #include<cs ...
- POJ 1185 炮兵阵地(状压DP)
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26426 Accepted: 10185 Descriptio ...
- Calculation(dfs+状压dp)
Problem 1608 - Calculation Time Limit: 500MS Memory Limit: 65536KB Total Submit: 311 Accepted: ...
- POJ 2411 Mondriaan's Dream -- 状压DP
题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...
- CODEVS1358【DFS/状压DP】
题目链接[http://codevs.cn/problem/1358/] 题意:这个游戏在一个有10*10个格子的棋盘上进行,初始时棋子位于左上角,终点为右下角,棋盘上每个格子内有一个0到9的数字,每 ...
- POJ 1795 DNA Laboratory (贪心+状压DP)
题意:给定 n 个 字符串,让你构造出一个最短,字典序最小的字符串,包括这 n 个字符串. 析:首先使用状压DP,是很容易看出来的,dp[s][i] 表示已经满足 s 集合的字符串以 第 i 个字符串 ...
随机推荐
- Python 问题集
1.问题:打开Python的IDLE(集成开发环境/Integrated DeveLopment Environment) 然后在Python的shell中做如下动作时: >>>py ...
- bzoj2748:[HAOI2012]音量调节
思路:刷水有益健康. #include<iostream> #include<cstdio> #include<cstring> #include<algor ...
- N的N次方(高校俱乐部)
最近一直在刷字符串和线段树,也越来越少玩高校俱乐部,无聊看到一题N的N次方的问题,脑海中各种打表就涌现出来了. 弄了不一会儿,就写完了,马上提交,但是系统好像出了问题,提示"哦哦,出了点状况 ...
- C++ 代码性能优化 -- 循环分割提高并行性
对于一个可结合和可交换的合并操作来说,比如整数的加法或乘法, 我们可以通过将一组合并操作分割成 2 个或更多的部分,并在最后合并结果来提高性能. 原理: 普通代码只能利用 CPU 的一个寄存器,分割后 ...
- html常用单词和各种少见标签
常用单词: 空格 align="left"valign="top"align="center"valign="middle&qu ...
- 阿里云 CentOS 安装JDK
初用阿里云,使用centOS linux64操作系统 . 自己上传jdk文件总是安装失败,原因估计是因为我的网络不好,导致文件损坏. 解决办法,直接在linux命令行模式下,到官网下载 jdk,命令如 ...
- PHP中使用curlL实现GET和POST请求的方法
基本结构 (1)初始化 curl_init() (2)设置变量 curl_setopt() .最为重要,一切玄妙均在此.有一长串cURL参数可供设置,它们能指定URL请求的各个细节.要一次性全部看完并 ...
- CentOS7 IP自动获取
/etc/sysconfig/network-scripts HWADDR=00:15:5D:00:76:04TYPE=EthernetBOOTPROTO=dhcpDEFROUTE=yesPEERDN ...
- 【BZOJ】1012: [JSOI2008]最大数maxnumber 树状数组求区间最值
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1012 题意:维护一个数列,开始时没有数值,之后会有两种操作, Q L :查询数列末 ...
- PL/SQL — 显式游标
一.游标的相关概念及特性 1.定义 通过游标方式定位到结果集中某个特定的行,然后根据业务需求对该行进行相应特定的操作. 2.分类 显示游标: 用户自定义游标,用于处理select语句返回的多行数据. ...