zoukankan      html  css  js  c++  java
  • bzoj1087: [SCOI2005]互不侵犯King 状压dp

    在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。

    第一眼看成k皇后问题了,仔细一看原来是状压dp,dp【i】【j】【k】i是滚动数组压缩形式,j是上一层的状态,k是已经用过的国王数,那么转移很明显,从上一层转移到下一层,枚举两层的所有状态看会不会冲突,不冲突就能转移,d[now][j][num+k]+=dp[pre][i][k],now是这一层用过的国王数。,最后记录满足条件的k即可,复杂度O(n^2*2^2n),大约是1e8

    /**************************************************************
        Problem: 1087
        User: walfy
        Language: C++
        Result: Accepted
        Time:572 ms
        Memory:4604 kb
    ****************************************************************/
     
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
     
    using namespace std;
     
    const double g=10.0,eps=1e-12;
    const int N=1000+10,maxn=100000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
     
    ll dp[2][N][200+10];
    int main()
    {
        int n,k;
        scanf("%d%d",&n,&k);
        int now=1,pre=0;
        for(int i=0;i<(1<<n);i++)
        {
            int num=0,ok=1;
            for(int j=0;j<n;j++)
            {
                if((i>>j)&1)num++;
                if(j&&((i>>(j-1))&1)&&((i>>j)&1)){ok=0;break;}
            }
            if(ok)
            {
                dp[pre][i][num]++;
    //            printf("%d %d %d
    ",i,num,dp[pre][i][num]);
            }
        }
        for(int _=2;_<=n;_++)
        {
            memset(dp[now],0,sizeof dp[now]);
            for(int i=0;i<(1<<n);i++)//last
            {
                for(int j=0;j<=k;j++)//last k
                {
                    for(int u=0;u<(1<<n);u++)
                    {
                        if(dp[pre][i][j]==0)continue;
                        int num=0,ok=1;
                        for(int v=0;v<n;v++)
                        {
                            int st=(u>>v)&1,last=(i>>v)&1;
                            if((u>>v)&1)num++;
                            if(st&&last)
                            {
                                ok=0;
                                break;
                            }
                            if(v>0)
                            {
                                last=(i>>(v-1))&1;
                                if(st&&last){ok=0;break;}
                                last=(u>>(v-1))&1;
                                if(st&&last){ok=0;break;}
                            }
                            if(v<n-1)
                            {
                                last=(i>>(v+1))&1;
                                if(st&&last){ok=0;break;}
                                last=(u>>(v+1))&1;
                                if(st&&last){ok=0;break;}
                            }
                        }
                        if(ok)
                        {
    //                        printf("last = %d ++ last k = %d ++ now = %d dp[pre][i][j] = %d ++ num+j = %d
    ",i,j,u,dp[pre][i][j],num+j);
                            dp[now][u][num+j]+=dp[pre][i][j];
    //                        printf("%d %d %d %d
    ",now,u,num+j,dp[now][u][num+j]);
                        }
                    }
                }
            }
            swap(now,pre);
        }
        ll ans=0;
        for(int i=0;i<(1<<n);i++)
            ans+=dp[pre][i][k];
        printf("%lld
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    HDU_2955_Robberies_01背包
    01背包
    最长升序子序列
    快速排序
    HDU_1875_畅通工程再续
    iOS app 设计推荐
    iOS 两种方法实现左右滑动出现侧边菜单栏 slide view
    iOS 8自动调整UITableView和UICollectionView布局
    iOS app发布流程
    iOS博客推荐
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/8831828.html
Copyright © 2011-2022 走看看