HDU 4539 状压DP

这道题是腾讯马拉松的题,中文题,就不解释题意了。

状压DP,同炮兵阵地,写着练练手。

攻击范围是曼哈顿距离2,画个图能知道是这样的

       x

    x    x

x     o     x

下半部分就不画了。其实就是裸题。

 

#include <set>

#include <map>

#include <stack>

#include <cmath>

#include <queue>

#include <cstdio>

#include <string>

#include <vector>

#include <iomanip>

#include <cstring>

#include <iostream>

#include <algorithm>

#define Max 2505

#define FI first

#define SE second

#define ll long long

#define PI acos(-1.0)

#define inf 0x3fffffff

#define LL(x) ( x << 1 )

#define bug puts("here")

#define PII pair<int,int>

#define RR(x) ( x << 1 | 1 )

#define mp(a,b) make_pair(a,b)

#define mem(a,b) memset(a,b,sizeof(a))

#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )



using namespace std;



inline void RD(int &ret) {

    char c;

    int flag = 1 ;

    do {

        c = getchar();

        if(c == '-')flag = -1 ;

    } while(c < '0' || c > '9') ;

    ret = c - '0';

    while((c=getchar()) >= '0' && c <= '9')

        ret = ret * 10 + ( c - '0' );

    ret *= flag ;

}



inline void OT(int a) {

    if(a >= 10)OT(a / 10) ;

    putchar(a % 10 + '0') ;

}



/*********************************************/

#define N 1005

#define M 11

int n , m ;

int Map[111][11] ;

int MM[111] ;

int st[170] ;

int cnt[170] ;

int num = 0 ;

int dp[105][170][170] ;//j上一状态,k当前状态.

void ok(){

    for (int i = 0 ; i < 1 << m ; i ++ ){

        if((i >> 2) & i) continue ;

        if((i << 2) & i) continue ;

        int x = i ;

        int nn = 0 ;

        while(x){

            nn += x & 1 ;

            x >>= 1 ;

        }

        st[num] = i ;

        cnt[num ++] = nn ;

    }

}

int main() {

//    for (int i = 1 ; i <= 10 ;i ++ ){

//        num = 0 ;

//        m = i ;

//        ok() ;

//        cout << num << endl ;

//    }

    while(cin >> n >> m){

        mem(MM ,0) ;

        mem(dp ,0) ;

        num = 0 ;

        for (int i = 1 ; i <= n ; i ++ ){

            for (int j = 1 ; j <= m ; j ++ ){

                RD(Map[i][j]) ;

                if(!Map[i][j])MM[i] += 1 << ( j - 1 ) ;

            }

        }

        ok() ;

        int ans = 0 ;

        //预处理第一行

        for (int i = 0 ; i < num ; i ++ ){

            if(st[i] & MM[1])continue ;

            dp[1][0][i] = max(dp[1][0][i] , cnt[i]) ;

            ans = max(ans , dp[1][0][i]) ;

        }

        for (int i = 2 ; i <= n ; i ++ ){

            for (int j = 0 ; j < num ; j ++ ){

                if(MM[i - 1] & st[j])continue ;

                for (int k = 0 ; k < num ; k ++ ){

                    if(MM[i] & st[k])continue ;

                    if(st[k] >> 1 & st[j])continue ;

                    if(st[k] << 1 & st[j])continue ;

                    for (int l = 0 ; l < num ; l ++ ){

                        if(MM[i - 2] & st[l])continue ;

                        if(st[k] & st[l])continue ;

                        dp[i][j][k] = max(dp[i][j][k] , dp[i - 1][l][j] + cnt[k]) ;

                        ans = max(dp[i][j][k] , ans) ;

                    }

                }

            }

        }

        OT(ans) ;puts("") ;

    }

    return 0 ;

}


 

 

你可能感兴趣的:(HDU)