【状态压缩dp】【轮廓线dp】【互不侵犯King】【HYSBZ】【BZOJ】【1087】
2017-07-11 20:42
211 查看
这里是22平方傻君 , 长久没有更过博客了嘞,那么今天就来谈谈一道有趣的状态压缩题(孙便让各位进入轮廓线的深坑之中,轮廓线赛高,miku sama赛高)
左下右上右下八个方向上附近的各一个格子,共8个格子。
首先声明,轮廓线是一种特殊的状态压缩模型。。。这东西开始学起来的时候是需要毁一下我们对状态压缩的三官,但是学会后其实会发现它是一个挺巧妙的dp思想;
轮廓线dp一般适用于方格中的操作,比如说放插头填充方块(插头dp问题),互补干扰放置问题(乱取的名字),这道题其实就是后者,各个国王的放置需要满足一定的放置条件;这一类问题几乎都是可以用另外的装压dp来解决,但是这些装压dp的思路有的会十分巧妙难想(就好比一些几何题目的巧解),而用轮廓线解题则是有规律的而且好想的(可以想成是解几何题是用的建坐标系爆算),而且只要把所有情况考虑周全便会变的佷简单;
若是没有学过轮廓线或是对它还不太熟悉的话,建议可以看看刘汝佳大大的蓝书中的对应章节;在学习之前我建议可以把轮廓线理解为是一个会滑动的状态。。。就像一条蛇一样。。。就像这样:
蛇身上的每个格子就是一个状态,然后它就开始沿着整个区域开始s型滑动;
那么这道题也是如此:
一下便是我的代码:
然而这道题目。。。那个N <= 9 的条件已经很明显的说明了这道题是状压了嘛 , 而且还是一道相对比较裸的题目,裸题啊。。。然后。。。我就开心的去写轮廓线去了(虽然说轮廓线其实也是一种状压)。。。考试后看了一下黄学长的博文 , 结果发现确实状态压缩的思路还是佷巧妙的。。。
链接:http://hzwer.com/1461.html
problem:
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)Output
方案数。Sample Input
3 2Sample Output
16解法一:轮廓线dp:
首先声明,轮廓线是一种特殊的状态压缩模型。。。这东西开始学起来的时候是需要毁一下我们对状态压缩的三官,但是学会后其实会发现它是一个挺巧妙的dp思想;
轮廓线dp一般适用于方格中的操作,比如说放插头填充方块(插头dp问题),互补干扰放置问题(乱取的名字),这道题其实就是后者,各个国王的放置需要满足一定的放置条件;这一类问题几乎都是可以用另外的装压dp来解决,但是这些装压dp的思路有的会十分巧妙难想(就好比一些几何题目的巧解),而用轮廓线解题则是有规律的而且好想的(可以想成是解几何题是用的建坐标系爆算),而且只要把所有情况考虑周全便会变的佷简单;
若是没有学过轮廓线或是对它还不太熟悉的话,建议可以看看刘汝佳大大的蓝书中的对应章节;在学习之前我建议可以把轮廓线理解为是一个会滑动的状态。。。就像一条蛇一样。。。就像这样:
蛇身上的每个格子就是一个状态,然后它就开始沿着整个区域开始s型滑动;
那么这道题也是如此:
一下便是我的代码:
#include<cstdio> #include<cctype> #include<cstring> #include<iostream> #include<algorithm> #define M 100000 using namespace std; int dp[2][81][1<<11] , n , m , cur ; long long ans(0); int main(){ scanf("%d %d",&n,&m); int all = (1<<n+1) - 1; for(int i = 1 ; i <= n*n ; cur^=1, i++){ memset(dp[cur] , 0 , sizeof dp[cur]); dp[cur^1][0][0] = 1; for(int k = 1 ; k <= m ; k++){ for(int j = 0 ; j <= all ; j++){ dp[cur][k][j>>1] += dp[cur^1][k][j]; if(i%n == 1 && (j&6) == 0 )dp[cur][k][(j>>1) | (1<<n)]+=dp[cur^1][k-1][j]; else if(i%n == 0 && (j&3) == 0 && (j&(1<<n)) == 0)dp[cur][k][(j>>1) | (1<<n)]+=dp[cur^1][k-1][j]; else if((j&7) == 0 && (j&(1<<n)) == 0)dp[cur][k][(j>>1) | (1<<n)]+=dp[cur^1][k-1][j]; } } } for(int i = 0 ; i <= all ; i++)ans+=dp[cur^1][m][i]; printf("%lld",ans); }
解法二:状态压缩dp
然而这道题目。。。那个N <= 9 的条件已经很明显的说明了这道题是状压了嘛 , 而且还是一道相对比较裸的题目,裸题啊。。。然后。。。我就开心的去写轮廓线去了(虽然说轮廓线其实也是一种状压)。。。考试后看了一下黄学长的博文 , 结果发现确实状态压缩的思路还是佷巧妙的。。。
链接:http://hzwer.com/1461.html
相关文章推荐
- [BZOJ]1087: [SCOI2005]互不侵犯King 状态压缩DP
- 【bzoj1087】互不侵犯King 状态压缩dp
- 【bzoj1087】互不侵犯King 状态压缩dp
- [BZOJ 1087][SCOI2005]互不侵犯King:状态压缩DP
- 【状态压缩DP】【BZOJ1087】【SCOI2005】互不侵犯king
- 【状态压缩DP】BZOJ1087-[SCOI2005]互不侵犯King
- [bzoj1087][DP][状态压缩]互不侵犯King
- [BZOJ 1087][SCOI 2005] 互不侵犯King 状态压缩DP
- BZOJ 状态压缩dp 1087: [SCOI2005]互不侵犯King
- BZOJ 1087 互不侵犯King 状态压缩DP
- bzoj 1087 [SCOI2005]互不侵犯King 状态压缩dp
- BZOJ题目1087: [SCOI2005]互不侵犯King(状态压缩DP)
- BZOJ1087 [SCOI2005]互不侵犯King 状态压缩DP
- bzoj1087: [SCOI2005]互不侵犯King(状态压缩+Dp)
- 【BZOJ】1087 [SCOI2005]互不侵犯King 状压DP(轮廓线DP)
- BZOJ_P1087&Codevs_P2451 [SCOI2005]互不侵犯King(状态压缩DP)
- BZOJ 1087: [SCOI2005]互不侵犯King 状态压缩 题解
- 【轮廓线DP,状压DP】BZOJ1087 [SCOI2005]互不侵犯King
- 【浅谈轮廓线DP】BZOJ1087(SCOI2005)[互不侵犯King]题解
- D 1087: [SCOI2005]互不侵犯King (状态压缩dp)