HDU 5691 Sitting in Line Pressure dp

Keywords: PHP

Topic link: http://acm.hdu.edu.cn/showproblem.php?pid=5691
Title:
Given n n n numbers, let you choose a sequence that maximizes the sum of the product of two adjacent numbers in the sequence.
Solution:
Pressure DP. After compressing the states of all the numbers, we can do DP on this basis. It can be seen that this DP is related to the order. We need to add one dimension to represent the last added element. That is, dp[i][j] represents the maximum value of the last added element in the I state.
We traverse all states. For each state, we count the number of num in 1, which indicates that num number has already been added in this state. Next we need to add num+1 number. We need to traverse the last added element of i state, then enumerate the elements that can be added, and update the state that i state can be transferred to. Of course, we need to judge when num+1 number is added. Is it necessary to fix the position? If it's fixed, transfer it directly.

//HDU 5691

#include <bits/stdc++.h>
using namespace std;
const int maxn = 16;
const int inf = 0x3f3f3f3f;
int dp[1<<16][17]; //The state is i, and the last number is the maximum of a[j].
int a[17], p[17];
int main(){
    int T, n, ks = 0;
    scanf("%d", &T);
    while(T--){
        scanf("%d", &n);
        for(int i = 0; i < n; i++){
            scanf("%d%d", &a[i], &p[i]);
        }
        for(int i = 0; i < (1<<n); i++){
            for(int j = 0; j < n; j++){
                dp[i][j] = -inf;
            }
        }
        for(int i = 0; i < n; i++){//Initialization is only possible if p[i]=0 or p[i]=-1
            if(p[i] == 0 || p[i] == -1) 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){//When it is the first p[k] or p[k] is - 1, it can continue to put in.
                    for(int k = 0; k < n; k++){
                        if(((1<<k)&i) == 0 && ((p[k] == __builtin_popcount(i)) || 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]);
        }
        printf("Case #%d:\n", ++ks);
        printf("%d\n", ans);
    }
    return 0;
}

Posted by vickyjackson on Thu, 14 Feb 2019 13:09:18 -0800