HDU5961 Sitting in Line【状压DP】

Topic link: HDU5961 Sitting in Line

Question: Give you n numbers and their positions. If the position is -1, it means that the number can take any position. Choose a placement method that maximizes the sum of the products of two adjacent numbers;

Analysis: N<=16, consider the state pressure DP; dp[i][j] represents the answer when the number 1 in state i is placed in front and j is placed in this place; when dp[i][j] is established Dp[i|(1<<k)][k] can be updated backwards from it, please note that the position of this bit can be placed at will or the position it needs to be placed is exactly the current processing position when updating;

#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int dp[(1<<17)+1][17],a[17],p[17];
//dp[i][j] 取状态i中为1的数放在前面且这一位放j时的答案
int rua()
{
    int n;scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d%d",&a[i],&p[i]);
    memset(dp,-INF,sizeof(dp));
    for(int i=0;i<n;i++) if(p[i]<=0) dp[(1<<i)][i]=0;
    for(int i=0;i<(1<<n);i++)
        for(int j=0;j<n;j++)
        {
            if(dp[i][j]==-INF) continue;
            for(int k=0;k<n;k++)
                if(((i&(1<<k))==0) && (__builtin_popcount(i)==p[k] || 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 i=0;i<n;i++) ans=max(ans,dp[(1<<n)-1][i]);
    return ans;
}
int main()
{
    int t;scanf("%d",&t);
    for(int id=1;id<=t;id++) printf("Case #%d:\n%d\n",id,rua());
    return 0;
}

 

Guess you like

Origin blog.csdn.net/qq_43813163/article/details/102834449