LOJ3215 「PA 2019」 Pop Music

The meaning of problems

Given \ (n-\) integers \ (a_i \) and an integer \ (m \) . Locate the \ (n-\) non-negative integer, satisfying \ (b_0 <b_1 <b_2 < \ dots <b_ n \) and \ (\ sum \ text {popcount } (b_i) \ times a_i \) is the maximum value
\ (1 \ le n \ le 200 , n-1 \ le m \ le 10 ^ {18} \)

Thinking

If \ (m \) is relatively small, this question is obviously interval \ (\ DP {text} \) , \ (A [L, R & lt] \) corresponding to \ ([L, R] \ ) node. But now \ (m \) is particularly large, because to be useful bits, we can think of using \ (\ text {trie} \ ) tree. Konjac first reaction: to build it out? But we found that if each \ (\ text {trie} \ ) below nodes are full, they are all the same. I.e. we \ (m \ cdot \ text { log} m \) nodes, the nodes fall into two types, a second dimension \ (m * m \) of the reduced complexity of the \ (2 \) .

If the merger up from under, as long as we focus on whether this point is full of points, as well as the current contribution of this next layer, \ ([L, k] \) return to the left not contribute to his son, the son who owned the right to add \ (a [k + 1, r ] \) and.

  1. For a full point, two sons are also full points.
  2. For the last point on a node to the root path, you may not have the right son, then left his son a non-full points (not to say the following dissatisfaction, because it is difficult to consider, we just put the last of the points where the dragged out a special class treatment), can only put all the right son; there may have full and non-full left his son the right node, right node contributions doubled \ (a [k + 1, r] \) . Interval dp

In vain from konjac zjy to see a lot of people do not have the patience to see a man I might, if you really want to study you can go zsy chiefs there to see

#include <bits/stdc++.h>
const int N=305;
using std::max;
typedef long long ll;
int n;
ll m,a[N],f[2][2][N][N];
int main(){
    scanf("%d%lld",&n,&m);
    for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for (int i=1;i<=n;i++) a[i]+=a[i-1];
    int now=0;
    memset(f[now],-63,sizeof(f[now]));
    for (int i=1;i<=n;i++) f[now][0][i][i]=f[now][1][i][i]=0; 
    for (int w=1;1ll<<(w-1)<=m;w++){
        now=now^1;
        memset(f[now],-63,sizeof(f[now]));
        for (int len=1;len<=n;len++)
            for(int l=1,r=len;r<=n;l++,r++){
                f[now][0][l][r]=f[now^1][0][l][r]+max(0ll,a[r]-a[l-1]);
                for (int k=l;k<r;k++)
                    f[now][0][l][r]=max(f[now][0][l][r],f[now^1][0][l][k]+f[now^1][0][k+1][r]+a[r]-a[k]);
                if ((m>>(w-1))&1){
                    f[now][1][l][r]=max(f[now^1][0][l][r],f[now^1][1][l][r]+a[r]-a[l-1]);
                    for (int k=l;k<r;k++)
                        f[now][1][l][r]=max(f[now][1][l][r],f[now^1][0][l][k]+f[now^1][1][k+1][r]+a[r]-a[k]);
                }else f[now][1][l][r]=f[now^1][1][l][r];
        }
    }
    printf("%lld\n",f[now][1][1][n]);
} 

postscript

Large make up blog site (up finish up)

Guess you like

Origin www.cnblogs.com/flyfeather6/p/12234956.html
PA
pop
PA1