• 【状压DP(奇怪的东西)】


     简介

     状态压缩动态规划(简称状压DP)是非常典型的一类DP。他是利用二进制来描述状态的一种DP方式,大家都知道,DP是解决多阶段决策最优化问题的思想方法,但是有时候阶段多了,维度多了,数组也就爆了,因为虽然维度多,但是有些空间可能用不到,这就很浪费了,(主要是维度多了处理麻烦很恶心)所以我们就把我们就把一组数据压到一个int变量里面(只要是整形,什么都好啦)

      举个生动形象的例子,在01背包中,n个物品的选择方式,就可以用二进制数来表示:1 0 1 1 0(n=5),从低位开始,表示1不选,2选,3选,4不选,5选。

      既然它与二进制有关,所以我们就需要讲一讲二进制啦

    位运算

    基本运算

    名称

    作用

    举例

    左移(<<) 位左移运算将整个数按位左移若干位,左移后空出的部分0。 5(101)<<2=20(10100) 
    右移(>>) 位右移运算将整个数按位右移若干位,右移后空出的部分填0。 5(101)>>2=1(1) 
    按位与(&) 会将两个十进制数在二进制下进行与运算,然后返回其十进制下的值。在某一位上,只有两个数都是1才返回1 5(101)&2(10)=0 
    按位或(|) 会将两个十进制数在二进制下进行或运算,然后返回其十进制下的值。在某一位上,只要有一个数是1就返回1 5(101)|2(10)=7(111) 
    按位异或(^) 会将两个十进制数在二进制下进行异或运算,然后返回其十进制下的值。在某一位上,只有两个数相同才返回1 5(101)^2(10)=0 
    按位非(~) 把0变成1,1变成0,然后返回其十进制下的值。 咳咳,最好不要轻易用,因为int有32位(二进制),前面的全部会变成1 

    进阶运算

    检查第i位是否是 1

    if(1<<(i-1)&x)...

    检查第i位是否是 0

    if(1<<(i-1)&x==0)...

    统计x中有多少个 1

    while(x)
    {
        cnt += x&1;
        x >>= 1;
    }

    检查x中是否有相邻的 1

    if(x&(x<<1))...

    计算x最低位1代表的值

    int lowbit(int x)
    {
        return x&(-x);
    }

    把第i位变成 1

    x |= (1<<(i-1))

    把第i位变成 0

    x &= ~(1<<(i-1))

    把第i位取反

    x ^= (1<<(i-1)

    末i位取反

    x^(1<<(i-1))

    x包含y

    if(x&y==y)...    OR if(x|y==x)...

    取右边连续的1

    (x^(x+1))>>1

    把右边连续的0变成1

    x&(x-1)

    把右边连续的1变成0

    x|(x+1)

    把右边第一个0变成1

    x|(x+1)

    例题 P1879 [USACO06NOV]玉米田Corn Fields

      这是一道典型的状压DP(废话,学的状压不给状压给什么)

      我们用一个M数组来存储每一行的情况(土地是否贫瘠),然后用state数组表示某一种种植方法是否可以满足任意两个种植物不相邻,(bool数组)。

      然后开始一行一行的枚举状态,如果可用并且没有贫瘠土地,就枚举上一排的,看不相邻的情况就转移,最后把最后一行所有的情况累计起来即可。

    code

    例题 P1896 [SCOI2005]互不侵犯

      还是和玉米田差不多的操作,但是dp数组需要加一维,所以就成了在某一行的某种状态中已经放了x个国王有几种方法,剩下的就和上一个例题差不多了

    code

  • 相关阅读:
    ubuntu10官方镜像安装硬盘自动分区失败的问题
    ubuntu10的pci扩展卡驱动安装失败后检查方法
    day7集合
    day6字符编码
    day5 dict
    day4 list,tuple
    day2 int,bool,str
    day1
    函数一
    注册登录
  • 原文地址:https://www.cnblogs.com/hualian/p/11288544.html
Copyright © 2020-2023  润新知