[SCOI2005]互不侵犯 (状压$dp$)

题目链接


Solution

状压 \(dp\) .
\(f[i][j][k]\) 代表前 \(i\) 列中 , 已经安置 \(j\) 位国王,且最后一位状态为 \(k\) .
然后就可以很轻松的转移了...
记忆化搜索还是不够啊... 只能会正向 \(dp\) .

Code

#include<bits/stdc++.h>
#define ll long long
using namespace std;

ll f[10][101][1100],n,K;
ll js[1100],sum,ans;

int main()
{
    cin>>n>>K;
    sum=(1<<n)-1;

    for(ll i=0;i<=sum;i++)
    for(ll j=0;j<n;j++)
    if(i&(1<<j))js[i]++;

    for(ll i=0;i<=sum;i++)
    if((i<<1&i))continue;
    else f[1][js[i]][i]=1;

    for(ll i=1;i<n;i++)
    for(ll j=0;j<=K;j++)
    for(ll k=0;k<=sum;k++)
    {
        if(!f[i][j][k])continue;
        for(ll kk=0;kk<=sum;kk++)
        {
            if((kk<<1&kk))continue;
            if((k&kk)||((k>>1)&kk)||((k<<1)&kk))continue;
            if(j+js[kk]>K)continue;
            f[i+1][j+js[kk]][kk]+=f[i][j][k];
        }
    }
    for(ll i=0;i<=sum;i++)
    ans+=f[n][K][i];
    cout<<ans<<endl;
}

原文地址:https://www.cnblogs.com/Kv-Stalin/p/9794929.html

时间: 2024-08-29 23:39:35

[SCOI2005]互不侵犯 (状压$dp$)的相关文章

1896 [SCOI2005]互不侵犯 状压dp

传送门 这是一道状压dp的经典例题 题目让输出所有可能的方案数 很显然 这是一道动态规划了 由于国王放置的位置有一定的限制 所以我们要在状态转移的过程中增加一维来存储状态 我们这一道题假设f[i][j][k] 意思是在前i行一共放置了j个国王 第i行国王放置的状态是k  存储的值是方案数 首先 我们可以先预处理出左右合法的每行的状态...(有点绕 就是说针对单独的一行 会有那些合法的状态 使得相邻的两个格子最多只能放置一个国王 没有相邻的国王 然后我们开始dp 我们分别枚举i k s i是当前枚

BZOJ 1087: [SCOI2005]互不侵犯King( 状压dp )

简单的状压dp... dp( x , h , s ) 表示当前第 x 行 , 用了 h 个 king , 当前行的状态为 s . 考虑转移 : dp( x , h , s ) = ∑ dp( x - 1 , h - cnt_1( s ) , s' ) ( s and s' 两行不冲突 , cnt_1( s ) 表示 s 状态用了多少个 king ) 我有各种预处理所以 code 的方程和这有点不一样 ------------------------------------------------

BZOJ1087:[SCOI2005]互不侵犯King(状压DP)

[SCOI2005]互不侵犯King Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N) Output 方案数. Sample Input 3 2 Sample Output 16 分析: 经典的状压DP题目,可我竟然调了很长时间都没对,后来发现是DP枚举范围错

[Bzoj1083][SCOI2005]互不侵犯king(状压dp)

1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4595  Solved: 2664[Submit][Status][Discuss] Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K &

【题解】[SCOI2005] 互不侵犯 (状压DP)

[SCOI2005] 互不侵犯 终于懂一点状压DP了… 用一个数的二进制形式表示一整行的状态,比如 18(1010)表示第一列和第三列有国王. 然后用&判断是否可行: if((x&y)||((x<<1)&y)||(x&(y<<1))) continue;1code: #include<iostream>#include<cstdio>#include<cstring>#include<algorithm>

[SCOI2005]互不侵犯King

1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4255  Solved: 2458 [Submit][Status][Discuss] Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上 左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <=

SCOI2005互不侵犯King

1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1499  Solved: 872[Submit][Status] Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N

P1896 [SCOI2005]互不侵犯King

题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入输出格式 输入格式: 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N) 输出格式: 所得的方案数 输入输出样例 输入样例#1: 3 2 输出样例#1: 16 题解:状态压缩动规,用一个整型的二进制表示来表示棋盘上一行的情况,放了棋子为1,没放为0:可以先预处理出所有可能的状态:用位

[BZOJ1087] [SCOI2005] 互不侵犯King (状压dp)

Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N) Output 方案数. Sample Input 3 2 Sample Output 16 HINT Source Solution 状压$dp$就是把状态压缩成二进制数,利用二进制的位运算改进算法的一种方法