Astar Round2A 1002 Sitting in Line 记忆化搜索

来源:互联网 发布:软件测试免费教程 编辑:程序博客网 时间:2024/05/22 08:09

Sitting in Line

题意

给出n个数,和确定部分数的位置。要求最大的

i=1n1(a[i]a[i+1])

思路

从左到右前m个用的数字集市S,且最右边是pr的最优解。

dp[S][pr]=max(dp[s][i]+a[pr]a[i])

code

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define MAXN (20)#define INF  (999999999)int n;int a[MAXN], p[MAXN], c[MAXN];bool v[MAXN];int dp[(1<<16) + 5][MAXN];int dfs(int _s, int pr, int m) {  if (dp[_s][pr] != -INF) return dp[_s][pr];  if (m == n+1) return 0;  int rec = -INF;  if (c[m] == -1) {    for (int i=1; i<=n; i++) {      if ((_s & (1 << (i-1))) != 0) continue;      if (p[i] == -1) {        rec = max(rec, dfs(_s | (1 << (i-1)), i, m+1) + a[pr] * a[i]);      }    }  } else {    rec = max(rec, dfs(_s | (1 << c[m]-1), c[m], m+1) + a[pr] * a[c[m]]);  }  return dp[_s][pr] = rec;}int main() {  int T, cass = 0;  scanf ("%d", &T);  for (int cases = 1; cases <= T; cases ++) {    scanf ("%d", &n);    memset(c, -1, sizeof(c));    for (int i=1; i<=n; i++) {      scanf("%d %d", &a[i], &p[i]);      if (p[i] != -1) c[p[i]+1] = i;    }    for (int i=0; i<(1<<n); i++) {      fill(dp[i], dp[i] + n + 2, -INF);    }    printf("Case #%d:\n%d\n", ++cass, dfs(0, 0, 1));  }  return 0;}
0 0
原创粉丝点击