bzoj 1087

状压DP,数组范围没注意,搞了半天QAQ

感觉状压DP挺难调的

 1 #include<bits/stdc++.h>
 2 #define inc(i,l,r) for(int i=l;i<=r;i++)
 3 #define dec(i,l,r) for(int i=l;i>=r;i--)
 4 #define link(x) for(edge *j=h[x];j;j=j->next)
 5 #define mem(a) memset(a,0,sizeof(a))
 6 #define inf 1e9
 7 #define ll long long
 8 #define succ(x) (1<<x)
 9 #define NM 10
10 using namespace std;
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();}
14     while(isdigit(ch))x=x*10+ch-‘0‘,ch=getchar();
15     return x*f;
16 }
17 ll d[NM][succ(NM)][NM*NM],ans;
18 int k,n,m,c[succ(NM)],b[succ(NM)];
19 int main(){
20     n=read();k=read();
21     inc(i,0,succ(n)-1)
22     if(!(i&(i<<1)))b[++m]=i,c[m]=__builtin_popcount(i),d[1][m][c[m]]=1;
23     inc(i,2,n)
24     inc(t,1,m)
25     inc(v,0,k)
26     if(c[t]<=v){
27         int _t=0;
28         inc(j,0,n-1)
29         if((b[t]&succ(j-1))||(b[t]&succ(j))||(b[t]&succ(j+1)))_t+=succ(j);
30         inc(j,1,m)
31         if(!(b[j]&_t)&&c[t]<=v)
32         d[i][t][v]+=d[i-1][j][v-c[t]];
33     }
34 //    inc(i,1,n){inc(t,1,m){
35 //    inc(j,0,k)printf("%d ",d[i][t][j]);
36 //    printf("\n");}
37 //    printf("\n");}
38     inc(t,1,m)ans+=d[n][t][k];
39     printf("%lld\n",ans);
40     return 0;
41 }

时间: 2024-10-09 22:22:58

bzoj 1087的相关文章

BZOJ 1087状态压缩DP

状态压缩DP真心不会写,参考了别人的写法. 先预处理出合理状态, 我们用二进制表示可以放棋子的状态,DP[I][J][K]:表示现在处理到第I行,J:表示第I行的状态,K表示现在为止一共放的棋子数量. #include<stdio.h> #include<iostream> #define N 1111 using namespace std; typedef long long ll; int num,n,m; ll dp[11][1<<11][90]; int hh

BZOJ 1087 互不侵犯King (位运算)

题解:首先,这道题可以用位运算来表示每一行的状态,同八皇后的搜索方法,然后对于限制条件不相互攻击,则只需将新加入的一行左右移动与上一行相&,若是0则互不攻击,方案可行.对于每种方案,则用递推来统计,将前一排所有可以的情况全部加上即可.bit数组记录每个数字二进制位中1的个数,方便计算. if(check(j,q))f[i][j][k]+=f[i-1][q][k-bit[j]]; #include <iostream> #define rep(i,n) for (int i=0;i<

BZOJ 1087: [SCOI2005]互不侵犯King( 状压dp )

简单的状压dp... dp( x , h , s ) 表示当前第 x 行 , 用了 h 个 king , 当前行的状态为 s . 考虑转移 : dp( x , h , s ) = ∑ dp( x - 1 , h - cnt_1( s ) , s' ) ( s and s' 两行不冲突 , cnt_1( s ) 表示 s 状态用了多少个 king ) 我有各种预处理所以 code 的方程和这有点不一样 ------------------------------------------------

BZOJ 1087 题解【状压DP】

1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3112  Solved: 1816[Submit][Status][Discuss] Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K &

【状压dp】【bzoj 1087】【SCOI 2005】互不侵犯King

1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MB Submit: 1991 Solved: 1185 Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N) Output 方案数. Sa

bzoj 1087 状压dp

1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4130  Solved: 2390[Submit][Status][Discuss] Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上 左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K

BZOJ 1087 [SCOI2005]互不侵犯King

水状压 预处理可以用的每行的状态,转移的时候判断上下行是否冲突.记得当时刚学的时候听学长讲感觉这题好难呀. 然后智障的第一次空间开小了第二次忘了开LL,RE了一发又WA了一发... #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #include<vector>

互不侵犯King(bzoj 1087)

Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N) Output 方案数. Sample Input 3 2 Sample Output 16 /* 一看就是状压DP,而且状态也很好设,dp[i][j][s]表示前i行填了j个国王,第i行的状态是s的方案数. 但

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

Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N) Output 方案数. Sample Input 3 2 Sample Output 16 同学很早之前打表过了,orz 这题正解状压DP,f[i][s][k]表示第i行上一行的状态为S,选了k个 预处理出所有