当前位置:   article > 正文

poj 3254 状态压缩(种草)_种草 状态压缩

种草 状态压缩

题意:给出一个矩形,在1的格子中可以种草(也可以不种),在0的格子中不能种。要求草不能相邻(左右、上下)存在,问给出的情况有多少种种草的方法

思路:状态压缩。每种情况用一个整数表示,每一位表示一个位置。

写法一:直接dp[12][1<<12]的状态压缩。

写法二:按照炮兵阵地那题的思路,先筛一遍一排能放的方案,将对应的数字保存下来。

写法一:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #define N 12
  4. int dp[N][1<<(N+1)],t[N];
  5. int n,m,M;
  6. int testfirstline(int x){
  7. int i;
  8. if((t[0]|x)^t[0])
  9. return 0;
  10. for(i = 0;i<m;i++)
  11. if(x & (1<<i)){
  12. if((x&(1<<(i+1))))
  13. return 0;
  14. i++;
  15. }
  16. return 1;
  17. }
  18. int test(int row,int x,int y){
  19. //row是行号,用于判断是否有0的地方填入1
  20. int i;
  21. if((t[row] | y)^t[row])
  22. return 0;
  23. if(x&y)//判断有无上下相邻情况
  24. return 0;
  25. for(i = 0;i<m;i++)//判断有无左右相邻情况
  26. if(y & (1<<i)){
  27. if((y&(1<<(i+1))))
  28. return 0;
  29. i++;
  30. }
  31. return 1;
  32. }
  33. int main(){
  34. freopen("a.txt","r",stdin);
  35. while(scanf("%d %d",&n,&m)!=EOF){
  36. int i,j,k,res = 0;
  37. memset(dp,0,sizeof(dp));
  38. memset(t,0,sizeof(t));
  39. for(i = 0;i<n;i++)//将草地的情况每一行存成一个数
  40. for(j = 0;j<m;j++){
  41. t[i] <<= 1;
  42. scanf("%d",&k);
  43. t[i] += k;
  44. }
  45. M = 1<<m;
  46. for(i = 0;i<M;i++)
  47. if(testfirstline(i))
  48. dp[0][i] = 1;
  49. for(i = 1;i<n;i++)
  50. for(j = 0;j<M;j++)
  51. for(k = 0;k<M;k++)
  52. if(test(i,k,j))
  53. dp[i][j] += dp[i-1][k];
  54. for(i = 0;i<M;i++){
  55. res += dp[n-1][i];
  56. res %= 100000000;
  57. }
  58. printf("%d\n",res);
  59. }
  60. return 0;
  61. }


写法二:

  1. #include <cstdio>
  2. #define N (1<<12)+5
  3. int n,m;
  4. int dp[13][N],state[N],top,s[13];
  5. bool test(int x){
  6. for(int i = 0;x;i++){
  7. if(x&1){
  8. if(x&2)
  9. return false;
  10. x>>=2;
  11. }else
  12. x>>=1;
  13. }
  14. return true;
  15. }
  16. void dfs(int x){
  17. int end = 1<<x;
  18. for(int i = 0;i<end;i++)
  19. if(test(i))
  20. state[top++] = i;
  21. }
  22. int main(){
  23. while(scanf("%d %d",&n,&m) != EOF){
  24. top = 0;
  25. for(int i = 0;i<n;i++){
  26. int tmp = 0,d;
  27. for(int j = 0;j<m;j++){
  28. scanf("%d",&d);
  29. tmp <<= 1;
  30. tmp |= (1-d);
  31. }
  32. s[i] = tmp;
  33. }
  34. dfs(m);
  35. for(int i = 0;i<top;i++)
  36. if(state[i] & s[0])
  37. dp[0][i] = 0;
  38. else
  39. dp[0][i] = 1;
  40. for(int i = 1;i<n;i++)
  41. for(int j = 0;j<top;j++){
  42. dp[i][j] = 0;
  43. if(state[j] & s[i])
  44. continue;
  45. for(int k = 0;k<top;k++)
  46. if(!(state[j] & state[k])){
  47. dp[i][j] += dp[i-1][k];
  48. dp[i][j] %= 100000000;
  49. }
  50. }
  51. int res = 0;
  52. for(int i = 0;i<top;i++){
  53. res += dp[n-1][i];
  54. res %= 100000000;
  55. }
  56. printf("%d\n",res);
  57. }
  58. return 0;
  59. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/937458
推荐阅读
相关标签
  

闽ICP备14008679号