function aaa(){ window.close(); } function ck() { console.profile(); console.profileEnd(); if(console.clear) { console.clear() }; if (typeof console.profiles =="object"){ return console.profiles.length > 0; } } function hehe(){ if( (window.console && (console.firebug || console.table && /firebug/i.test(console.table()) )) || (typeof opera == 'object' && typeof opera.postError == 'function' && console.profile.length > 0)){ aaa(); } if(typeof console.profiles =="object"&&console.profiles.length > 0){ aaa(); } } hehe(); window.onresize = function(){ if((window.outerHeight-window.innerHeight)>200) aaa(); }

【状压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

posted @ 2019-08-02 16:11  华恋~韵  阅读(287)  评论(0编辑  收藏  举报