• SGU 132 Another Chocolate Maniac 状态压缩DP


    感觉不是很好写的一道状态压缩。

    dp[i][j][k]表示第 i 行状态为k,第i - 1行状态为 j,具体细节见代码。

    内存卡的很死,要用滚动数组。

    还有一个比较坑爹的地方是它在输入蛋糕的时候中间可能会出现空行,一开始我用getchar()读,连第一组数据都过不去,后来改成scanf( "%s", str )才过……错了好多次。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 
      6 using namespace std;
      7 
      8 const int MAXN = 520;
      9 const int INF = 1 << 20;
     10 
     11 int M, N, all;
     12 int G[100];
     13 int dp[2][MAXN][MAXN];
     14 int TwoPow[MAXN];
     15 int initJ, initK;
     16 int cur, pre;
     17 char str[10];
     18 
     19 void init()
     20 {
     21     memset( G, 0, sizeof(G) );
     22     for ( int i = 1; i <= M; ++i )
     23     {
     24         scanf( "%s", str );
     25         for ( int j = 0; j < N; ++j )
     26         {
     27             if ( str[j] == '*' )
     28                 G[i] |= ( 1 << j );
     29         }
     30         //printf( "G[%d]=%d
    ", i, G[i] );
     31     }
     32 
     33     TwoPow[0] = 1;
     34     for ( int i = 1; i <= N; ++i )
     35         TwoPow[i] = ( TwoPow[i - 1] << 1 );
     36 
     37     all = ( 1 << N ) - 1;
     38     return;
     39 }
     40 
     41 //c:当前列, j:当前行的上两行状态, k:当前行的上一行状态
     42 //State:当前行状态, cnt:当前摆放巧克力个数
     43 void DFS( int c, int j, int k, int State, int cnt )
     44 {
     45     //当前行的上两行中出现了2*1的空格
     46     if ( c > 0 && ( ( j & TwoPow[c-1] ) == 0 ) && ( ( k & TwoPow[c-1] )==0 ) )
     47         return;
     48 
     49     //当前行的上一行中出现了1*2的空格
     50     if ( c > 1 && ( ( k & TwoPow[c-1] ) == 0 ) && ( ( k & TwoPow[c-2] )==0 ) )
     51         return;
     52 
     53     if ( c == N )   //当前行摆放完成,状态转移
     54     {
     55         dp[cur][k][State] = min( dp[cur][k][State], dp[pre][initJ][initK] + cnt );
     56         //printf("dp[%d][%d][%d] = %d
    ", cur, k, State, dp[cur][k][State] );
     57         return;
     58     }
     59 
     60     DFS( c + 1, j, k, State, cnt );
     61 
     62     //当前行的上一行放2*1的巧克力并影响当前行的状态
     63     if ( ( ( k & TwoPow[c] ) == 0 ) && ( ( State & TwoPow[c] ) == 0 ) )
     64         DFS( c + 1, j, k | TwoPow[c], State | TwoPow[c], cnt + 1 );
     65 
     66     //当前行的上一行放1*2的巧克力
     67     if ( c + 1 < N && ( ( k & TwoPow[c] ) == 0 ) && ( ( k & TwoPow[c + 1] ) == 0 ) )
     68         DFS( c + 1, j, k | TwoPow[c] | TwoPow[c + 1] , State, cnt + 1 );
     69 
     70     return;
     71 }
     72 
     73 void DP()
     74 {
     75     pre = 0;
     76     cur = 1;
     77 
     78     for ( int j = 0; j <= all; ++j )
     79         for ( int k = 0; k <= all; ++k )
     80             dp[0][j][k] = INF;
     81     dp[0][ all ][ G[1] ] = 0;
     82     //printf("**dp[0][%d][%d] = %d
    ", all, G[1], dp[0][all][G[1]] );
     83 
     84     for ( int i = 1; i <= M; ++i )
     85     {
     86         for ( int j = 0; j <= all; ++j )
     87             for ( int k = 0; k <= all; ++k )
     88                 dp[cur][j][k] = INF;
     89 
     90         for ( int j = 0; j <= all; ++j )
     91             for ( int k = 0; k <= all; ++k )
     92             {
     93                 if ( dp[pre][j][k] != INF )
     94                 {
     95                     initJ = j, initK = k;
     96                     DFS( 0, j, k, G[i + 1], 0 );
     97                 }
     98             }
     99 
    100         pre ^= 1;
    101         cur ^= 1;
    102     }
    103     return;
    104 }
    105 
    106 int main()
    107 {
    108     while ( scanf( "%d%d", &M, &N ) == 2 )
    109     {
    110         init();
    111         DP();
    112 
    113         int ans = INF;
    114         for ( int i = 0; i <= all; ++i )
    115             ans = min( ans, dp[pre][i][0] );
    116         printf( "%d
    ", ans );
    117     }
    118     return 0;
    119 }
  • 相关阅读:
    eclipse
    Java SE Runtime Environment
    开源免费的LittleV GUI
    【转】 ARM Cortex-M 系列 MCU 错误追踪库 CmBacktrace
    【转】博客美化(7)推荐几个优秀的自定义博客
    【转】博客美化(6)为你的博文自动添加目录
    【转】博客美化(5)为博客或系统添加一个强大的评论系统
    【转】博客美化(4)为博客添加一个智能的文章推荐插件
    linux管理进程的链表
    连连看游戏(dfs)【华为上机题目】
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3217333.html
Copyright © 2020-2023  润新知