HDU 4049 狀態壓縮DP

/*******************************************************************************
    去年北京賽區網絡賽水題,狀態壓縮DP,一開始TLE,然後發現是沒初始化,應該用空間換時間來着,
接着WA,搞了半天沒搞明白。。。最後發現發現一個小小的紕漏~~~
    解法就是建立狀態dp[M][1 << N],用第一個狀態表示第i個城市,第二個狀態表示決定在這個城市
裏遊玩的人的狀態,用二進制表示~然後就是很裸很裸的狀態壓縮DP了~
*******************************************************************************/
#include <iostream>
#include <functional>
#include <algorithm>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <utility>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <limits>
#include <memory>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;

#define LOWBIT(x) ( (x) & ( (x) ^ ( (x) - 1 ) ) )
#define CLR(x, k) memset((x), (k), sizeof(x))
#define CPY(t, s) memcpy((t), (s), sizeof(s))
#define SC(t, s) static_cast<t>(s)
#define LEN(s) static_cast<int>( strlen((s)) )
#define SZ(s) static_cast<int>( (s).size() )

typedef double LF;
typedef __int64 LL;		//VC
typedef unsigned __int64 ULL;

typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<double, double> PDD;

typedef vector<int> VI;
typedef vector<char> VC;
typedef vector<double> VF;
typedef vector<string> VS;

template <typename T>
T sqa(const T & x)
{
	return x * x;
}
template <typename T>
T gcd(T a, T b)
{
	if (!a || !b)
	{
		return max(a, b);
	}
	T t;
	while (t = a % b)
	{
		a = b;
		b = t;
	}
	return b;
};

const int INF_INT = 0x3f3f3f3f;
const LL INF_LL = 0x7fffffffffffffffLL;		//15f
const double oo = 10e9;
const double eps = 10e-7;
const double PI = acos(-1.0);

#define  ONLINE_JUDGE

const int MAXN = 12;
const int MAXM = 12;
const int MAXS = (1 << MAXN);

int n, m, cost[MAXM], inter[MAXN][MAXM], bonus[MAXN][MAXN];
int dp[2][MAXS], maze[MAXM][MAXS];
bool hs[MAXN];
VI G[MAXS];

int valueCount(int city, int status)
{
	int res = 0, bit = 0;
	CLR(hs, false);
	for (int ind = 0; ind < n; ++ind)
	{
		if (status & (1 << ind))
		{
			hs[ind] = true;
			++bit;
		}
	}
	res -= bit * cost[city];
	for (int i = 0; i < n; ++i)
	{
		if (hs[i])
		{
			res += inter[i][city];
		}
	}
	for (int i = 0; i < n; ++i)
	{
		if (!hs[i])
		{
			continue ;
		}
		for (int j = i + 1; j < n; ++j)
		{
			if (hs[j])
			{
				res += bonus[i][j];
			}
		}
	}
	return res;
}
bool inline containsJudge(const int & lhs, const int & rhs)
{
	return (lhs & rhs) == lhs;
}
void init()
{
	int buf = (1 << n);
	for (int city = 0; city < m; ++city)
	{
		for (int ind = 0; ind < buf; ++ind)
		{
			maze[city][ind] = valueCount(city, ind);
		}
	}
	for (int i = 0; i < buf; ++i)
	{
		G[i].clear();
		for (int j = i + 1; j < buf; ++j)
		{
			if (containsJudge(i, j))
			{
				G[i].push_back(j);
			}
		}
	}
	return ;
}
int solve()
{
	CLR(dp[0], -INF_INT);
	CLR(dp[1], 0);
	int res = 0, buf = (1 << n);
	for (int ind = 0, k = 0; ind < m; ++ind, k ^= 1)
	{
		for (int crt = 0; crt < buf; ++crt)
		{
			dp[k][crt] = dp[k ^ 1][crt] + maze[ind][crt];
			res = max(res, dp[k][crt]);						//TMD相當無語了。。。
			for (VI::iterator it = G[crt].begin(); it != G[crt].end(); ++it)
			{
				int nxt = *it;
				dp[k][crt] = max(dp[k][crt], dp[k ^ 1][nxt] + maze[ind][crt]);
				res = max(res, dp[k][crt]);
			}
		}
	}
	return res;
}
void ace()
{
	int ans;
	while (cin >> n >> m, n || m)
	{
		for (int i = 0; i < m; ++i)
		{
			cin >> cost[i];
		}
		for (int i = 0; i < n; ++i)
		{
			for (int j = 0; j < m; ++j)
			{
				cin >> inter[i][j];
			}
		}
		for (int i = 0; i < n; ++i)
		{
			for (int j = 0; j < n; ++j)
			{
				cin >> bonus[i][j];
			}
		}
		init();
		ans = solve();
		if (0 >= ans)
		{
			puts("STAY HOME");
			continue ;
		}
		cout << ans << endl;
	}
	return ;
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	ace();
	return 0;
}
/*******************************************************************************
Test Data...

2 1
10
15
5
0 5
5 0
3 2
30 50
24 48
40 70
35 20
0 4 1
4 0 5
1 5 0
2 2
100 100
50 50
50 50
0 20
20 0
0 0
*******************************************************************************/

發佈了75 篇原創文章 · 獲贊 1 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章