HDU 1565 方格取数(1)(状态压缩DP)

来源:互联网 发布:python 求平均值 编辑:程序博客网 时间:2024/05/20 04:10

题目链接:HDU 1565 方格取数(1)

挺简单的一个状压DP,因为一点小失误搞了好久。。

先按最大值跑一遍getState可以知道一行可以有多少种状态,就是MAX_K。状态转移方程:dp[s][i] = max(dp[s][i], dp[j][i - 1] + getSum(state[s], i)),dp[s][i]表示第i行在状态state[s]下可以取到的前i行的最大值。

#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int MAX_N = 20;const int MAX_S = (1 << MAX_N) + 100;const int MAX_M = MAX_N + 5;const int MAX_K = 17745 + 1000;int dp[MAX_K][MAX_M];int _map[MAX_M][MAX_M];int state[MAX_K];int n, cnt;bool is_ok(int s){    if(s & (s << 1))        return false;    return true;}int getSum(int s, int i){    int res = 0;    int k = 0;    while(s > 0)    {        if(s & 1)            res += _map[i][k];        s = s >> 1;        k++;    }    return res;}int getState(){    cnt = 0;    int len = (1 << n) - 1;    for(int s = 0; s <= len; s++)        if(is_ok(s))            state[cnt++] = s;    return cnt;}int main(){    //freopen("in.txt", "r", stdin);    while(scanf("%d", &n) != EOF)    {        memset(dp, 0, sizeof(dp));        for(int i = 0; i < n; i++)            for(int j = 0; j < n; j++)                scanf("%d", &_map[i][j]);        getState();        int _max = 0;        for(int s = 0; s < cnt; s++)            dp[s][0] = getSum(state[s], 0);        for(int i = 1; i < n; i++)        {            for(int s = 0; s < cnt; s++)            {                for(int j = 0; j < cnt; j++)                {                    if(state[s] & state[j])                        continue;                    dp[s][i] = max(dp[s][i], dp[j][i - 1] + getSum(state[s], i));                }            }        }        for(int s = 0; s < cnt; s++)            _max = max(_max, dp[s][n - 1]);        printf("%d\n", _max);    }    return 0;}



0 0
原创粉丝点击