首页 > 其他 > 详细

BZOJ 1087 [SCOI2005]互不侵犯King

时间:2017-09-18 20:59:26      阅读:290      评论:0      收藏:0      [点我收藏+]

 

水状压

预处理可以用的每行的状态,转移的时候判断上下行是否冲突。记得当时刚学的时候听学长讲感觉这题好难呀。

然后智障的第一次空间开小了第二次忘了开LL,RE了一发又WA了一发。。。

技术分享
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
typedef long long LL;
using namespace std;
LL n,nn,kk,ok[600],in[600],dp[10][900][100],ans;
void init() {
    scanf("%lld%lld",&n,&kk);
}
void pre() {
    nn=(1<<n)-1;
    for(int i=0;i<=nn;i++) { 
        int pre=-1;
        for(int j=0;j<=8;j++) {
          if(i&(1<<j)) {
                if(j+1-pre<2) break;
                in[i]++;
                pre=j+1;
          }
          if(j==8) ok[i]=1;
        }
    }
}
int check(int a,int b) {
    for(int i=0;i<=8;i++) {
        if(a&(1<<i)) {
            if(b&(1<<i)) return 0;
            if(i-1>=0&&(b&(1<<i-1))) return 0;
            if(i+1<=8&&(b&(1<<i+1))) return 0;
        }
    }
    return 1;
}
void solve() {
    for(int i=0;i<=nn;i++) if(ok[i]) dp[1][i][in[i]]=1;
    for(int i=2;i<=n;i++) {
        for(int j=0;j<=nn;j++) if(ok[j]){
            for(int k=0;k<=nn;k++) if(ok[k]) {
                if(check(j,k)){
                    for(int l=0;l<=kk;l++) if(l+in[j]<=kk){
                        dp[i][j][l+in[j]]+=dp[i-1][k][l]; 
                    }
                }
            }
        }
    }
    for(int i=0;i<=nn;i++) 
        if(ok[i]) 
        ans+=dp[n][i][kk];
    printf("%lld\n",ans);
}
int main()
{
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    init();
    pre();
    solve();
    return 0;
}
View Code

 

BZOJ 1087 [SCOI2005]互不侵犯King

原文:http://www.cnblogs.com/Achenchen/p/7545056.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!