hdu5691--Sitting in Line(状压DP,2016百度之星Round2A/1002)

来源:互联网 发布:javascript取数组分割 编辑:程序博客网 时间:2024/05/22 02:14

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


分析:看到N的范围,八成就是状压。q[i]表示第i个位置填第几个数。

          状态:dp[i][j]表示用了i这种情况里这些数,从左往右填以j为结尾的最大值。

          状态转移方程:当第k个位置已经被固定填什么数时,向状态st里添加i并以i为结尾,dp[st|(1<<q[k])][q[k]] = max(dp[st|(1<<q[k])][q[k]], dp[st][j]+a[j]*a[q[k]])。当第k位置不固定,枚举各个数,该数不在集合时,便添加到集合里,dp[st|(1<<i)][i] = max(dp[st|(1<<i)][i], dp[st][j]+a[j]*a[i])。


代码:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int N = 20;const ll INF = 1LL<<50;ll dp[1<<N][N];int p[N], q[N], a[N];int main() {    int T, n;    scanf("%d", &T);    for(int kase = 1; kase <= T; kase++) {        scanf("%d", &n);        memset(q, -1, sizeof(q));        for(int i = 0; i < n; i++) {            scanf("%d%d", &a[i], &p[i]);            if(p[i] >= 0) q[p[i]] = i;        }        for(int i = 0; i < (1<<n); i++)            for(int j = 0; j < n; j++)                dp[i][j] = -INF;        if(~q[0]) dp[1<<q[0]][q[0]] = 0;        else {            for(int i = 0; i < n; i++)                dp[1<<i][i] = 0;        }        for(int st = 1; st < (1<<n); st++) {            int k = 0;            for(int i = 0; i < n; i++)                k += st>>i&1;            if(~q[k]) {                if(st & (1<<q[k])) continue;                for(int j = 0; j < n; j++) {                    if(~st&(1<<j)) continue;                    dp[st|(1<<q[k])][q[k]] = max(dp[st|(1<<q[k])][q[k]], dp[st][j]+a[j]*a[q[k]]);                }            }            else {                for(int i = 0; i < n; i++) {                    if(st & (1<<i)) continue;                    for(int j = 0; j < n; j++) {                        if(~st&(1<<j)) continue;                        dp[st|(1<<i)][i] = max(dp[st|(1<<i)][i], dp[st][j]+a[j]*a[i]);                    }                }            }        }        ll ans = -INF;        for(int i = 0; i < n; i++)            ans = max(ans, dp[(1<<n)-1][i]);        printf("Case #%d:\n%I64d\n", kase, ans);    }    return 0;}


0 0
原创粉丝点击