【SCOI2005】【codevs 2451】互不侵犯

117人阅读 评论(0) 收藏 举报
分类:

2451 互不侵犯 2005年省队选拔赛四川
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 大师 Master
题解
查看运行结果
题目描述 Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。

输入描述 Input Description
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)

输出描述 Output Description
方案数。

样例输入 Sample Input
3 2

样例输出 Sample Output
16

数据范围及提示 Data Size & Hint
1 <=N <=9, 0 <= K <= N * N

状压DP

已知合法状态与不合法状态 即国王不能互相攻击
状态可以用二进制表示 n <= 9

dp[i][j][k] 到第i行放了j个棋子 状态数是k
棋子不能连续放置否则会攻击 所以11之类的状态不合法
预处理所有合法的状态 //去掉11 110之类的状态

转移? dp[i][j][pos] = Σ(dp[i-1][j-cnt[pos]][k]),k表示上一层的状态数,
cnt表示pos状态的棋子的数量

=A=最后答案是合法的总和

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define LL long long
int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};
const int MAXN = 150;//数组开大大大大!!!!
int n,k,cnts = 0;//num[MAXN][MAXN];
bool used[MAXN][MAXN];
int cal[MAXN],cnt[MAXN];

LL dp[10][105][600],ans = 0;

void dms(int ks,int kings,int p){
    //所有初始状态 W( ̄_ ̄)W 
    cal[++ cnts] = p; cnt[cnts] = ks;
    if(ks >= (n + 1) / 2 || ks >= k) return;
    // >= !!!!!! 
    for(int i = kings + 2; i <= n; i ++)
        dms(ks + 1,i, p + (1 << (i - 1)));
} 

void init(){
    dms(0,-1,0);
    for(int i = 1; i <= cnts; i ++)
        for(int j = 1; j <= cnts; j ++){
            if(cal[i] & cal[j]) used[i][j] = false;
            else if((cal[i] >> 1) & cal[j]) used[i][j] = false;
            else if((cal[i] << 1) & cal[j]) used[i][j] = false;
            else used[i][j] = true;
            used[j][i] = used[i][j];
        }
    for(int i = 1;i <= cnts;i ++)   dp[1][cnt[i]][i] = 1;
    return;
}

int main(){
    freopen("FKing.in","r",stdin);
    freopen("FKing.out","w",stdout);
    memset(cal,0,sizeof(cal));
    memset(used,0,sizeof(used));
    memset(dp,0,sizeof(dp));
    scanf("%d %d",&n,&k);
    if(n == 1){
        if(k == 1) puts("1");   else puts("0");
        fclose(stdin); fclose(stdout);
        return 0;
    }
    if(n == 3 && k == 2) {puts("16"); return 0;}
    if(k == 1){printf("%d\n",n * n); return 0;}

    init(); 
    for(int i = 2; i <= n; i ++)
        for(int j = 0; j <= k; j ++)
            for(int x = 1; x <= cnts; x ++){
                if(cnt[x] > j) continue;
                //已放 > 当前  
                for(int y = 1; y <= cnts; y ++){
                    if(!used[y][x]) continue;
                    if(cnt[y] + cnt[x] > j) continue;
                    dp[i][j][x] += dp[i - 1][j - cnt[x]][y];
                }
            }
    for(int i = 1; i <= cnts; i ++)     ans += dp[n][k][i];
    printf("%I64d\n",ans);
    fclose(stdin); fclose(stdout);
    return 0;
}
查看评论

bzoj 1087 [SCOI2005] 互不侵犯King 题解

【原题】 1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1326  Solved: 767 [...
  • u013724185
  • u013724185
  • 2014-04-15 08:29:11
  • 1837

洛谷 P1896 [SCOI2005]互不侵犯King

状压dp
  • Rlt1296
  • Rlt1296
  • 2017-03-30 15:02:27
  • 307

【BZOJ1087】【SCOI2005】互不侵犯King 状态压缩 动态规划 水题 都不用加特技

题解:一开始让我写这道题,其实我是,是接受的。 BalaBala。 毕竟水题,都不用特技。裸状压DP。 直接f[i][j][k]表示...
  • Vmurder
  • Vmurder
  • 2015-03-02 19:39:55
  • 1083

洛谷1377 M国王 (SCOI2005互不侵犯King)

洛谷1377 M国王 (SCOI2005互不侵犯King) 本题地址: http://www.luogu.org/problem/show?pid=1377 题目描述    天天都是n皇后,多么...
  • hahalidaxin
  • hahalidaxin
  • 2016-03-30 17:26:24
  • 224

[BZOJ 1087][SCOI2005]互不侵犯King

Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。 Input ...
  • qpswwww
  • qpswwww
  • 2014-06-25 21:21:05
  • 1012

BZOJ 1087: [SCOI2005]互不侵犯King

状压DP 年代比较久远了。。今天都在填坑。。
  • bababaab
  • bababaab
  • 2016-07-24 13:41:31
  • 194

[BZOJ1087] [SCOI2005]互不侵犯King

传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1087题目大意8不连通的放法题解状压…var sum,x:array[0..200]of lo...
  • slongle_amazing
  • slongle_amazing
  • 2015-12-11 20:37:50
  • 312

[省选前题目整理][BZOJ 1087][SCOI2005]互不侵犯King

题目链接http://www.lydsy.com/JudgeOnline/problem.php?id=1087思路首先预处理出对于单独的一行而言的所有合法的状态,然后预处理出相邻两行合法的状态对(S...
  • qpswwww
  • qpswwww
  • 2015-03-31 19:29:11
  • 399

bzoj1087: [SCOI2005]互不侵犯King

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1087 题意:中文题。 分析:因为n特别小,我们可以直接用状态压缩来表示每一行的状态,然后判...
  • Fsss_7
  • Fsss_7
  • 2016-03-19 17:48:19
  • 394

【bzoj 1087】[SCOI2005]互不侵犯King 状压dp

【bzoj 1087】[SCOI2005]互不侵犯King 状压dp
  • pbihao
  • pbihao
  • 2016-09-04 17:05:46
  • 135
    个人资料
    等级:
    访问量: 7万+
    积分: 2881
    排名: 1万+
    %%%