zoukankan      html  css  js  c++  java
  • bzoj1087互不侵犯King——状压DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1087

    水题...

    然而犯了两个致命小错误,调了好半天...详见注释。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int n,m,s[1<<9],cnt,num[1<<9];
    bool sid[1<<9][1<<9];
    ll f[15][1<<9][90],ans;
    int cal(int x)
    {
        int ret=0;
        while(x){if(x&1)ret++;x>>=1;}
        return ret;
    }
    void init()
    {
        for(int i=0;i<=(1<<n)-1;i++)//别误写成1<<(n-1) ! 
        {
            if(i&(i>>1))continue;
            s[++cnt]=i;
            num[cnt]=cal(i);
        }
        for(int i=1;i<=cnt;i++)
            for(int j=i;j<=cnt;j++)//不是从i+1,因为0和0可以相邻 
                if((s[i]&s[j])==0&&(s[i]&(s[j]>>1))==0&&(s[i]&(s[j]<<1))==0)
                    sid[i][j]=1,sid[j][i]=1;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        init();
        for(int i=1;i<=cnt;i++)f[1][i][num[i]]=1;
        for(int i=2;i<=n;i++)
            for(int j=1;j<=cnt;j++)
                for(int k=1;k<=cnt;k++) if(sid[j][k])
                    for(int l=num[k];l<=m;l++)
                    {
                        f[i][k][l]+=f[i-1][j][l-num[k]];
    //                    if(f[i-1][j][l-num[k]])printf("i=%d : %d->%d ,l=%d f=%d
    ",i,s[j],s[k],l,f[i][k][l]);
                    }        
        for(int i=1;i<=cnt;i++)
            ans+=f[n][i][m];
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    2017暑期集训Day 1
    17-06-28模拟赛
    17-06-26模拟赛
    平衡树学习笔记
    指针学习笔记
    17-06-14模拟赛
    17-06-11模拟赛
    17-06-02模拟赛
    17-05-31模拟赛
    培训补坑(day1:最短路&two-sat)
  • 原文地址:https://www.cnblogs.com/Zinn/p/9142126.html
Copyright © 2011-2022 走看看