hdu 5691 Sitting in Line 状压dp

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 5691 Sitting in Line 状压dp相关的知识,希望对你有一定的参考价值。

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5691

题解:

和tsp用的状压差不多,就是固定了一些访问顺序。

dp[i][j]表示前cnt个点中布满状态i且最后一个为j的状态的最大乘积和。

则有dp[i|(1<<k)][k]=max(dp[i|(1<<k)][k],dp[i][j]+a[j]*a[k])。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn = 22;
const int INF = 2e9;
int dp[1 << 16][22];
int cnt[1 << 16];
int a[maxn], p[maxn],f[maxn];
int n;

void pre() {
    for (int i = 0; i < (1 << 16); i++) {
        cnt[i] = 0;
        for (int j = 0; j < 16; j++) {
            if (i&(1 << j)) cnt[i]++;
        }
    }
}

void init() {
    for (int i = 0; i < (1 << n); i++) {
        for (int j = 0; j <= n; j++) {
            dp[i][j] = -INF;
        }
    }
    memset(f, -1, sizeof(f));
}

int main() {
    pre();
    int tc,kase=0;
    scanf("%d", &tc);
    while (tc--) {
        scanf("%d", &n);
        init();
        for (int i = 0; i < n; i++) {
            scanf("%d%d", a + i, p + i);
            if (p[i] != -1) f[p[i]] = i;
        }
        a[n] = 0; p[n] = n;
        dp[0][n] = 0; 
        for (int i = 0; i < (1 << n); i++) {
            int sum = cnt[i];
            for (int j = 0; j <= n; j++) {
                if ((i&(1 << j)) == 0&&j!=n) continue;
                //被限制的点:
                if (f[sum] != -1) {
                    if ((i&(1 << f[sum])) == 0) {
                        dp[i | (1 << f[sum])][f[sum]] =
                            max(dp[i | (1 << f[sum])][f[sum]], dp[i][j]+a[j]*a[f[sum]]);
                    }
                }
                else {
                    //可以自由移动的点
                    for (int k = 0; k < n; k++) {
                        if (i&(1 << k)) continue;
                        if (p[k] ==-1) {
                            dp[i | (1 << k)][k] = max(dp[i | (1 << k)][k], dp[i][j] + a[j] * a[k]);
                        }
                    }
                }
            }
        }
        int ans = -INF;
        for (int j = 0; j < n; j++) ans = max(ans, dp[(1 << n) - 1][j]);
        printf("Case #%d:\n", ++kase);
        printf("%d\n", ans);
    }
    return 0;
}

 

以上是关于hdu 5691 Sitting in Line 状压dp的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5691 Sitting in Line

hdu 5691 Sitting in Line(状压dp)

hdu 5691 Sitting in Line (状压dp)

HDU5691 Sitting in Line状压DP

hdu 5691 Sitting in Line 状压dp

HDU 5691 Sitting in Line 状压dp