状态压缩-动态规划

状态压缩-动态规划

---By蒟蒻鱼

用二进制表示城市的到达(规划的)状态
每一个二进制数都代表一个唯一的十进制数



预备知识

  • 位运算

优先级

~
<< 和 >>
&
^
|

按位与 & 全一则一,否则为零

按位或 | 有一则一,否则为零

按位取反 ~ 是零则一,是一为零

按位异或 ^ 不同则一,相同为零

移位 >> <<



基本运算:

集合取并 A|B

集合取交 A&B

集合相减 A&~B

集合相减 ALLBITS~A

置位 A|1<<bit

清位 A^(1<<bit)



TSP问题

dp[i][j]代表已经走过城市的方案为i,当前所在j号城市的最短路径的长度
DP方程:
dp[i][j]=min(dp[i^(1<<j-1)][k]+dis[k][j])
i^(1<<j-1)清除j的前驱

合法布阵问题

corn fields

玉米田
时间限制:2000毫秒内存限制:65536K
提交总数:21933接受:11472
描述

农场主约翰购买了一个郁郁葱葱的新矩形牧场,由m×n(1≤m≤12;1≤n≤12)个方形地块组成。他想在一些广场上为奶牛种些好吃的玉米。遗憾的是,有些广场是不孕的,不能种植。Canny FJ知道奶牛不喜欢互相靠近吃东西,所以在选择种植哪种方块时,他避免选择相邻的方块;没有两个选择的方块共用一个边。他还没有最终决定种植哪种方块。

作为一个非常开明的人,农夫约翰想考虑所有可能的选择,如何选择广场种植。他是如此的开明,他认为选择没有广场是一个有效的选择!请帮助农夫约翰确定他可以选择种植方块的方法的数量。

输入

第1行:两个空格分隔的整数:m和n
第2.m+1行:第i+1行描述牧场的第一行,用N个空格分隔的整数表示一个正方形是否可育(1表示可育,0表示不可育)
产量

第1行:一个整数:FJ选择平方模10000000的方法数。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int mod=100000000;

int n,m;
int st[1<<12],map[1<<12];//分别表示每一行的状态和草地的状态
int dp[15][1<<12]; 

int main()
{
    scanf("%d%d",&n,&m);
    int x;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&x);
            if(x==0)map[i]=map[i]|(1<<j-1);
        }
    int k=0;
    for(int i=0;i<(1<<m);i++)//计算每行合法的放置方式
    {
        if(!(i&(i<<1)))st[++k]=i;
    }
    for(int i=1;i<=k;i++)//特判第一行
    {
        if(!(st[i]&map[1]))dp[1][i]=1;
    }
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=k;j++)
        {
            if(!(map[i]&st[j]))for(int r=1;r<=k;r++)
            {
                if(!(map[i-1]&st[r]))
                {
                    if(!(st[j]&st[r]))dp[i][j]+=dp[i-1][r];
                }
            }
        }
    }
    int ans=0;
    for(int i=1;i<=k;i++)

    {
        ans=(ans+dp[n][i])%mod;
    }
    printf("%d",ans);
    return 0;
}


end

原文地址:https://www.cnblogs.com/XJack/p/10868920.html

时间: 2024-08-27 06:43:24

状态压缩-动态规划的相关文章

奇妙的算法—状态压缩动态规划

华电北风吹 天津大学认知计算与应用重点实验室 日期:2015/8/27 由于代码未调试完全正确论文草稿呈现 poj上一道需要用到状态压缩动态规划,链接http://poj.org/problem?id=3254 网上看到有很多人写出了代码,参考了一个带备忘的自顶向下的动态规划解法,自己写了一个有底向上的动态规划解法 有底向上: #include<iostream> #include<math.h> #include<ostream> #include<fstrea

状态压缩动态规划总结

状态压缩是一个很广的概念,在OI中也有很多的应用,当我们把他应用到动态规划中,可以用来精简状态,节约空间,也方便转移.最常见的就是用二进制来表是状态,利用各种位移运算,就可以实现\(O(1)\)的转移.状压DP适用于“窄棋盘”上的DP,否则状态太多无法存下. POJ1185 炮兵阵地 题意:给一个\(N \times M\)的地形盘,有平原和山坡,要求在平原上部署尽量多的炮(攻击范围2),使得不互相攻击. 数据范围:N <= 100:M <= 10,符合条件.如何表示状态?按行DP,一个二进制

状态压缩动态规划 -- 炮兵阵地

司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队,一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格.图上其它白色网格均攻击不到.从图上可见炮兵的攻击

状态压缩动态规划 -- 棋盘问题 POJ 1321

一个 N * N 的棋盘上面,有些格子不能放,放置 M 的棋子, 每两个棋子不能在同一行或者同一列,问有多少种放法 DFS太慢,用SCR好点点 Python 只有 22 行,其实可以更短,但是得排成很长很长的一行 while True: table = [ [ 0 for j in range( 300 ) ] for i in range( 12 ) ] table[0][0] = 1 boardsize, chessnum = map( int, raw_input().split() )

状态压缩动态规划 -- 旅行商问题

旅行商问题: N个点(N<16)的带权有向图D,求一条路径,使得这条路经过每个点恰好一次, 并且路径上边的权值和最小(或者最大),或者求一条具有这样性质的回路. 状态压缩: 将二进制表示十进制数N的点集,比如: 10 = 0000000000001010 代表第1和3个点已经路过 18 = 0000000000010010 代表第1和4个点已经路过 一个整数就是一个点集, dp_arr[binary][to_]代表经过点集 binary 中,当前终点为to_, 且路径最短的值,若该状态不存在就是

状态压缩动态规划 -- 多米诺骨牌

用1*2 的骨牌通过组合拼成 m * n 的大矩形,问有几种拼法. 题目链接:http://poj.org/problem?id=2411 状态转移: 1.由于上一行的该列竖直放置骨牌为 0,影响到当前行的该列,当前行的该列为 1 2.当前行骨牌横放,上一行骨牌横放, 都为11 3.上一行该列置为 1,当前行当前列立着放为 0 #include <iostream> #include <cstring> using namespace std; #define MAXSIZE 12

CODEVS_2800 送外卖 状态压缩+动态规划

原题链接:http://codevs.cn/problem/2800/ 题目描述 Description 有一个送外卖的,他手上有n份订单,他要把n份东西,分别送达n个不同的客户的手上.n个不同的客户分别在1~n个编号的城市中.送外卖的从0号城市出发,然后n个城市都要走一次(一个城市可以走多次),最后还要回到0点(他的单位),请问最短时间是多少.现在已知任意两个城市的直接通路的时间. 输入描述 Input Description 第一行一个正整数n (1<=n<=15) 接下来是一个(n+1)

【BZOJ1087】【SCOI2005】互不侵犯King 状态压缩 动态规划 水题 都不用加特技

广告: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44022265"); } 题解: 一开始让我写这道题,其实我是,是接受的. BalaBala. 毕竟水题,都不用特技. 裸状压DP. 直接f[i][j][k]表示第i行状态时j,有k个落子时的方案数. 代码: #include <

[HNOI2012][BZOJ2734] 集合选数|状态压缩动态规划|思路题

2734: [HNOI2012]集合选数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 708  Solved: 414[Submit][Status][Discuss] Description <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中.同学们不喜欢这种具有枚举性 质的题目,于是把它变成了以下问题:对于任意一个正整数 n≤