• 【题解】BZOJ P1087 dp


    状压DP


    f[i][j][k]表示第i行,状态为j,用了k个国王

    s[]是当前状态,king[]是这一行用了几个国王

    用十进制数的二进制表示这一行的状态

    其余见注释

    code

    //
    //  main.cpp
    //  bzoj
    //
    //  Created by gengyf on 2019/7/25.
    //  Copyright © 2019 yifan Geng. All rights reserved.
    //
    
    #include <bits/stdc++.h>
    using namespace std;
    namespace gengyf{
    #define ll long long
    #define maxn 501
        inline int read(){
            int f=1,x=0;char s=getchar();
            while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
            while(isdigit(s)){x=x*10+s-'0';s=getchar();}
            return x*f;
        }
        ll f[10][15000][85];
        int n,k;
        ll s[500000],king[50000];
        ll ans,sum;
        void init(){
            int tot=(1<<n)-1;   //最多的情况,二进制下每一位都有国王
            for(int i=0;i<=tot;i++){
                if(!((i<<1)&i)){   //两个国王之间要隔一个
                    s[++ans]=i; 
                    int t=i;
                    while(t){  //判断这个状态有多少个国王(数有多少个1)
                        king[ans]+=t%2;
                        t/=2;
                    }
                }
            }
        }
        int main(){
            n=read();k=read();
            init();
            for(int i=1;i<=ans;i++){
                if(king[i]<=k){
                    f[1][i][king[i]]=1;
                }
            }
            for(int i=2;i<=n;i++)
                for(int j=1;j<=ans;j++)
                    for(int p=1;p<=ans;p++){
                        if(s[j]&s[p])continue; //上下不相邻
                        if(s[j]&(s[p]<<1))continue;  //右上角不能有
                        if((s[j]<<1)&s[p])continue;  //左上角也不能有
                        for(int u=1;u<=k;u++){
                            if(king[j]+u>k)continue;  //u表示这一行之前一共用了多少个国王
                            f[i][j][king[j]+u]+=f[i-1][p][u];
                        }
                    }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=ans;j++){
                    sum+=f[i][j][k];
                }
            printf("%lld",sum);
            return 0;
        }
    }
    signed main() {
        gengyf::main();
        return 0;
    }

     

  • 相关阅读:
    [转]检查浏览器是否支持javascript和cookie
    Ruby语法学习
    [转]Office Word 2007鼠标操作无效
    JS选择图片,显示缩略图
    IE开发工具条IEDevToolBar下载
    [转]120个 Web 开发工具 (下)
    JQuery收藏
    [转]120个 Web 开发工具 (上)
    [转]GridView自动序号
    [转]GridView 常用事件删除,更新,删除,取消等
  • 原文地址:https://www.cnblogs.com/gengyf/p/11253180.html
Copyright © 2020-2023  润新知