zoukankan      html  css  js  c++  java
  • dp--状压dp

    Problem Description

    互不侵犯
    在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。

    Analysis of ideas

    把每一行的每一个状态用一个二进制数表示
    定义dp[i][j][k]为第i行,状态为j,已经放了k个棋子的方案数

    Accepted code

    #pragma GCC optimize(2)
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    int n,k;
    
    int dp[10][1024][100];        //第i行状态为j,放了k个国王
    
    vector<int> v;            //枚举可用的状态
    
    
    int count(int x)        //计算x1的个数
    {
        int res = 0;
        while(x)
        {
            res += x%2;
            x /= 2;
        }
        return res;
    }
    
    signed main()
    {
        cin>>n>>k;
        int mx = 1<<n;                //状态最多有1<<n个
        for(int i = 0; i < mx; i++) 
        {
            if((i&(i<<1)) == 0 && (i&(i>>1)) == 0) v.push_back(i);            //左边和右边没有1就是可用的状态
        }
        dp[0][0][0] = 1;                //初始化
        for(int i = 1; i <= n; i++) 
        {
            for(int j : v)      //枚举第i行状态j
            {
                for(int l : v)      //枚举第i-1行l
                {   
                    if((j&l) || (j&(l<<1)) || (j&(l>>1))) continue;        //不能互相攻击到
                    for(int h = 0; h <= k; h++)            //枚举已经放置的国王个数
                    {
                        dp[i][j][h+count(j)] += dp[i-1][l][h];
                    }
                }
            }
        }
        int ans = 0;
        for(int i : v) 
        {
            ans += dp[n][i][k];
        }
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    rsync--数据镜像备份_转
    netcat
    tcpdump抓包
    find命令应用exec及xargs
    traceroute/tracert--获取网络路由路径
    TCP/IP各层协议数据格式
    (转)mq经验总结-转
    (转)WebSphere MQ基础命令
    MQ通道搭建以及连通性检查
    (转)java并发之CountDownLatch、Semaphore和CyclicBarrier
  • 原文地址:https://www.cnblogs.com/hezongdnf/p/12276068.html
Copyright © 2011-2022 走看看