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的主要内容,如果未能解决你的问题,请参考以下文章

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

hdu 5691 Sitting in Line