//这道题就只有我用的状态DP么?
//DP时取当前的试剂组合,得出它们组成各种试剂的最小热量,以组合为状态就好
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 7, inf = 0x7f7f7f7f;
struct Edge
{
int a, b, emit, nxt;
}edge[N * N];
int head[N], n, m, e;
int chemical[12];
int F[1100][N];
char dummy[N];
void addedge(int a, int b, int c, int emit)
{
edge[e].a = a, edge[e].b = b, edge[e].emit = emit;
edge[e].nxt = head[c];
head[c] = e++;
}
bool singlebit(int state)
{
while (!(state & 1))
state >>= 1;
return state == 1;
}
int bitmatch(int state, int c)
{
int pos = 0;
while (!(state & 1))
{
state >>= 1;
pos++;
}
return chemical[pos] == c;
}
int Dp(int state, int c)
{
int &ans = F[state][c];
if (ans != -1)
return ans;
if (singlebit(state))
return ans = bitmatch(state, c) ? 0 : inf;
ans = inf;
for (int i = 1, tmp1, tmp2; i != state; ++i)
if ((i & state) == i)
for (int cur = head[c]; cur != -1; cur = edge[cur].nxt)
if ((tmp1 = Dp(state - i, edge[cur].b)) != inf && (tmp2 = Dp(i, edge[cur].a)) != inf)
ans = min(ans, tmp1 + tmp2 + edge[cur].emit);
return ans;
}
int main()
{
#ifdef LOCAL
freopen("in", "r", stdin);
#endif // LOCAL
int T;
for (scanf("%d", &T); T--; )
{
memset(head, -1, sizeof(head));
e = 0;
scanf("%d", &m);
for (int i = 1; i <= m; ++i)
{
for (int j = 1, c, emit; j <= m; ++j)
{
scanf("%d%d", &c, &emit);
addedge(i, j, c, emit);
}
}
scanf("%d", &n);
for (int i = 0; i != n; ++i)
scanf("%d", &chemical[i]);
memset(F, -1, sizeof(F));
int ans = inf, state = (1 << n) - 1;
for (int i = 1; i <= m; ++i)
ans = min(ans, Dp(state, i));
printf("%d\n", ans);
scanf("%s", dummy);
}
return 0;
}
10604 - Chemical Reaction解题报告
最新推荐文章于 2015-03-16 19:58:57 发布