ZOJ 3471 Most Powerful(状态压缩DP)

题目链接:ZOJ 3471 Most Powerful

状态压缩dp, 1表示还没炸,0表示已经炸了,dp[s]表示当前状态为s时的最大威力,状态转移方程:dp[new_s] = max(dp[new_s], dp[s] + _map[i][j]),因为新状态的1的个数少于上一个状态,所以需要倒着推。

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int MAX_N = 10;
const int MAX_S = (1 << MAX_N) + 50;
const int MAX_M = MAX_N + 2;
int dp[MAX_S], _map[MAX_M][MAX_M];
int n;

int main()
{
    //freopen("in.txt", "r", stdin);
    while(scanf("%d", &n), n)
    {
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                scanf("%d", &_map[i][j]);
        int S = (1 << n) - 1;
        int new_s, _max = 0;
        for(int s = S; s >= 0; s--)
        {
            for(int i = 0; i < n; i++)
            {
                if((s & (1 << i)))
                {
                    for(int j = 0; j < n; j++)
                    {
                        if(i == j)
                            continue;
                        if((s & (1 << j)))
                        {
                            new_s = (s ^ (1 << j));
                            dp[new_s] = max(dp[new_s], dp[s] + _map[i][j]);
                            _max = max(_max, dp[new_s]);
                        }
                    }
                }
            }
        }
        printf("%d\n", _max);
    }
    return 0;
}


你可能感兴趣的:(ZOJ 3471 Most Powerful(状态压缩DP))