BZOJ 1087 [SCOI2005]互不侵犯King

暴力状压dp。。。

好久不写状压dp,先水一个~

 

View Code
 1 #include <iostream>

 2 #include <cstring>

 3 #include <cstdlib>

 4 #include <cstdio>

 5 #include <algorithm>

 6 

 7 #define N 1000

 8 

 9 using namespace std;

10 

11 int num,n,m;

12 int zt[N],gs[N];

13 long long dp[11][1<<11][90];

14 bool map[N][N];

15 

16 inline bool check(int x,int y)

17 {

18     if(x&(y<<1)) return false;

19     if(x&(y>>1)) return false;

20     if(x&y) return false;

21     return true;

22 }

23 

24 inline bool judge(int x)

25 {

26     if(x&(x<<1)) return false;

27     if(x&(x>>1)) return false;

28     return true;

29 }

30 

31 inline int getnum(int x)

32 {

33     int res=0;

34     while(x)

35     {

36         if(x&1) res++;

37         x>>=1;

38     }

39     return res;

40 }

41 

42 inline void prev()

43 {

44     int sum=(1<<n)-1;

45     for(int i=0;i<=sum;i++)

46         if(judge(i))

47         {

48             zt[++num]=i;

49             gs[num]=getnum(i);

50         }

51     for(int i=1;i<=num;i++)

52         for(int j=i;j<=num;j++)    

53             if(check(zt[i],zt[j]))

54                 map[j][i]=map[i][j]=true;

55 }

56 

57 inline void go()

58 {

59     dp[0][1][0]=1LL;

60     for(int i=0;i<n;i++)

61         for(int j=1;j<=num;j++)

62             for(int k=0;k<=m;k++)

63                 if(dp[i][j][k])

64                     for(int p=1;p<=num;p++)

65                         if(map[j][p]&&k+gs[p]<=m)

66                             dp[i+1][p][k+gs[p]]+=dp[i][j][k];

67     long long sum=0;

68     for(int i=1;i<=num;i++)

69         sum+=dp[n][i][m];

70     printf("%lld\n",sum);

71 }

72 

73 int main()

74 {

75     scanf("%d%d",&n,&m);

76     prev();

77     go();

78     return 0;

79 }

 

 

你可能感兴趣的:(ZOJ)