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 << ":\n";
    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;
}
posted @ 2020-06-09 14:03  _kiko  阅读(123)  评论(0编辑  收藏  举报