zoukankan      html  css  js  c++  java
  • 状态压缩与二进制

    自己最烦二进制,但还是痛定思痛,耐心学着...

    普通的数都是十进制,二进制便是逢2进一,我觉得它最大的用途就可以表示一系列的东西用于不用上,用则为1,不用为0,比如说四个物体,可以用1111表示,再把1111用十进制表示15,这样15就可以表示这一状态。

    说从最基础的说起:一般的n个物体,用二进制表示就需要有n个位置,这时的十进制是多少呢?可以用<<表示,例如1<<2,就表示100,那n个物体就需要1<<n,才能表示1后n个0,前面要多一个1,因为你要把n个1的情况也包括,例如:n=4,1<<4就表示10000,开数组后从0计数,就可以包括1111这种状态了,其实不难发现,1<<n和2的n次方是一样的.所以数据范围一般就是2的n次方倍时就可以考虑状压了。

    其次:要明白一些最基本的位运算的用法:&表示与,有0取0,|表示或,有1取1,^表示异或,相同取0,否则取1.这个对我来说挺难记得,我是这样记得:&,|,^,这三个顺序记好,之后就是0,1,是否相等...还有就是<<=就是数要向左移几位,后面用0补齐,例如:4<<2,4用二进制表示为100,操作后变成10000;相反>>=就是原数想右移,最后几位舍去,例如:4>>2就从100变成了1;

    说一些其他用法,基本上是状压DP需要的:如何判断一个二进制数的某一位是否为1或0呢?可以用&,|与1的左移,例如:if(i&1<<(j-1)) continue;表明如果i的二进制数如果第j位为1的话,就跳过;其实很好理解,1<<(j-1)就表示一个第j位为1,其余位为0的二进制数。此事用i与它做&运算,有0取0,所以除了第j位,其余位一定取0,那么如果第j位为0,整体就是0,不执行.相反,如果第j位为1,整体有值,进行continue。如果想要判断为0是跳过,只需在前面加上!即可.之后再说如何修改?即例如1011,如何改成1111,把0改成另一个状态.这时我们就要用上|,也就是有1取1,例如:i|1<<(j-1)(此时已判断过i的第j位为0)就表示i的第j位由0变成1.这个很好理解由于1<<(j-1)除了第j位上为1,其余位上都是0,此时的|相当于把i的其他位复制下来,只把第j位修改为1;

    好了说了这么多见题:

    此题我第一次看就想不到DP,因为它是排列型的问题.不知道该怎么用状态表示,之后才明白这时状压DP的例题...

    既然是排列,那我们就只能标记用于不用,用用过的推没用过的...

    代码:

    #include<bits/stdc++.h>
    #define ll long long
    #define _ 0
    using namespace std;
    const int maxn=20;
    ll f[1<<maxn][maxn],n,H,h[maxn],ans;
    int main()
    {
        freopen("1.in","r",stdin);
        cin>>n>>H;
        for(int i=1;i<=n;i++) cin>>h[i];
        for(int i=1;i<=n;i++) f[1<<(i-1)][i]=1; //对第i位只放i的初始化;
        for(int i=1;i<=(1<<n)-1;i++)
            for(int j=1;j<=n;j++) //枚举上一个 
                for(int k=1;k<=n;k++) //枚举当前放的
                {
                    if(i&1<<(k-1)) continue; //假如说当前k已经放过则跳过.
                    if(abs(h[k]-h[j])>H) f[i|1<<(k-1)][k]+=f[i][j];
                }
        for(int i=1;i<=n;i++) ans+=f[(1<<n)-1][i];
        cout<<ans<<endl;
        return (0^_^0);         
    }

    好了,就到这吧!

  • 相关阅读:
    html5+css3中的background: -moz-linear-gradient 用法 (转载)
    CentOS 安装Apache服务
    Linux 笔记
    CURL 笔记
    Spring Application Context文件没有提示功能解决方法
    LeetCode 389. Find the Difference
    LeetCode 104. Maximum Depth of Binary Tree
    LeetCode 520. Detect Capital
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode 136. Single Number
  • 原文地址:https://www.cnblogs.com/gcfer/p/11076578.html
Copyright © 2011-2022 走看看