HDU5691 Sitting in Line状压DP

Posted kikokiko

tags:

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

HDU5691 Sitting in Line

题意:

给出(n)个数字,有些数字的位置固定了,现在要求把所有没固定的数字放在一个位置,使得任意相邻两个位置的数字的相乘的和最大

题解:

(n)只有(16),考虑状压(DP)
(DP[msk][i])表示当前已经选了(msk)集合里的数字且最后一个数字下标是(i)的最大值

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 17;
const int INF = 0x3f3f3f3f;
int n,pos[MAXN],val[MAXN],A[MAXN],f[1<<16][MAXN],rps[MAXN];

void solve(int kase){
    memset(f,-0x3f,sizeof(f));
    memset(rps,0,sizeof(rps));
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> val[i] >> pos[i];
    for(int i = 1; i <= n; i++){
        pos[i]++;
        if(pos[i]) rps[pos[i]] = i;
    }
    f[0][0] = 0;
    for(int msk = 1; msk < (1<<n); msk++){
        int curpos = __builtin_popcount(msk);               //当前位置
        int prepos = curpos - 1;                            //上一个位置
        for(int i = 1; i <= n; i++){                        //枚举数字
            if(!(msk&(1<<(i-1)))) continue;                     //不在集合里
            if(rps[curpos]!=0 and (i!=rps[curpos])) continue;      //该位置的数字已经固定
            if(pos[i]!=0 and pos[i]!=curpos) continue;              //该数字的位置已经固定
            if(curpos==1){
                f[msk][i] = 0;
                continue;
            }
            for(int j = 1; j <= n; j++){
                if(i==j or !(msk&(1<<(j-1)))) continue;
                if(rps[prepos]!=0 and (j!=rps[prepos])) continue;
                if(pos[j]!=0 and pos[j]!=prepos) continue;
                if(f[msk^(1<<(i-1))][j]==-INF) continue;
                f[msk][i] = max(f[msk][i],f[msk^(1<<(i-1))][j] + val[j] * val[i]);
            }
        }
    }
    cout << "Case #" << kase << ":
";
    cout << *max_element(begin(f[(1<<n)-1]),end(f[(1<<n)-1])) << endl;;
}
int main(){
    ____();
    int t; cin >> t;
    for(int kase = 1; kase <= t; kase++) solve(kase);
    return 0;
}

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