经典的状态压缩DP,状态是f[i][j],表示第i行,以3进制j为状态。j的位代表一个格子,只能是:0表示第i行和第i - 1行都没有炮兵,1表示第i行没有炮兵而第i-1行有炮兵,2表示第i行有炮兵。然后用DFS进行状态转移。一开始我做了超时,后来预处理了一下合法状态,快了不少,才AC。


/*************************************************************************
Author: WHU_GCC
Created Time: 2007-9-29 20:53:51
File Name: pku1185.cpp
Description: 
***********************************************************************
*/

#include 
<iostream>
using namespace std;

#define out(x) (cout << #x << ": " << x << endl)
typedef 
long long int64;
const int maxint = 0x7FFFFFFF;
const int64 maxint64 = 0x7FFFFFFFFFFFFFFFLL;
template 
<class T> void show(T a, int n) for (int i = 0; i < n; ++i) cout << a[i] << ' '; cout << endl; }
template 
<class T> void show(T a, int r, int l) for (int i = 0; i < r; ++i) show(a[i], l); cout << endl; }

const int maxn = 110;
const int maxm = 11;
const int mask[] = {13927812437292187656119683590491771475314411594323};

int n, m;
int g[maxn][maxm];
int f[maxn][59049];
int ok_state[10000];
int len;
int bits[14];

inline 
int get_bit(int x, int k)
{
    
return x % mask[k + 1/ mask[k];
}


void dfs(int origin_state, int origin_line, int now_col, int delta)
{
    
if (now_col >= m)
    
{
        
int new_state = 0;
        
for (int i = 0; i < m; i++)
            
if (bits[i] > 0)
                new_state 
+= bits[i] * mask[i];

        f[origin_line 
+ 1][new_state] >?= f[origin_line][origin_state] + delta;
        
return;
    }

    
if (bits[now_col] == -1 && g[origin_line + 1][now_col] == 0)
    
{
        bits[now_col] 
= 2;
        dfs(origin_state, origin_line, now_col 
+ 3, delta + 1);
        bits[now_col] 
= -1;
    }

    dfs(origin_state, origin_line, now_col 
+ 1, delta);
}


void dfs1(int now_col, int new_state, int last1, int last2)
{
    
if (now_col >= m)
    
{
        ok_state[len
++= new_state;
        
return;
    }


    
if (last1 != 2 && last2 != 2)
        dfs1(now_col 
+ 1, new_state + 2 * mask[now_col], 2, last1);
    
if (last1 != 1 && last2 != 1)
        dfs1(now_col 
+ 1, new_state + mask[now_col], 1, last1);
    dfs1(now_col 
+ 1, new_state, 0, last1);
}


void pre_process()
{
    len 
= 0;
    dfs1(
00-1-1);
}


int dp()
{
    memset(f, 
-1sizeof(f));
    f[
0][0= 0;
    
for (int i = 0; i < n; i++)
    
{
        
for (int j = 0; j < len; j++)
            
if (f[i][ok_state[j]] != -1)
            
{
                
for (int k = 0; k < m; k++)
                    bits[k] 
= get_bit(ok_state[j], k) - 1;
                dfs(ok_state[j], i, 
00);
            }

    }

    
int ret = 0;
    
for (int i = 0; i < mask[m]; i++)
        ret 
>?= f[n][i];
    
return ret;
}


int main()
{
    
char s[22];
    scanf(
"%d%d"&n, &m);
    
for (int i = 1; i <= n; i++)
    
{
        scanf(
"%s", s);
        
for (int j = 0; j < m; j++)
            
if (s[j] == 'P')
                g[i][j] 
= 0;
            
else
                g[i][j] 
= 1;
    }

    pre_process();
    printf(
"%d\n", dp());
    
return 0;
}
posted on 2007-09-30 22:09 Felicia 阅读(1041) 评论(0)  编辑 收藏 引用 所属分类: 动态规划

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理