CF1238E.Keyboard Purchase explanations shaped pressure / DP subsetting

  • Author: zifeiy
  • Tags: shaped pressure DP, DP subsetting

Link Title: https://codeforces.com/contest/1238/problem/E
Title effect:
to give you a length \ (n (n \ le 10 ^ 5) \) of the string s and \ (m (m \ 20 is Le) \) , the string of prior \ (m \) lowercase letters.
Now you find a front \ (m \) a permutation p characters, generating a string s based on the arrangement of the p, and calculate the total costs.
Calculation cost is:
For example, I have now generated before the i-th character of the string s \ (1..i S_ {} \) , and now I want to generate a first character i + 1 \ (s_ {i + 1} \) , and I assume \ (S_I \) corresponding character is x, \ (S_ {I +. 1} \) corresponding character is y, and the character x in the arrangement of p in position \ (pos_x \) , character y position in the array is p \ (pos_y \) , then the generated character \ (s_ {i + 1} \) after an increase of the total cost of \ (| pos_x - pos_y | \) .
You need to find the minimum total cost of all permutations of the total cost of the minimum program of the corresponding program.

Topic analysis:
First, we can look at the official explanations :

Explain to the official website of which involved a "subset dynamic programming", I would roughly translate it as "a subset of dynamic programming", in fact, the purpose of this question can be found in the sub-1 really set with some exercises.
At the same time it is compressed with the state also has some relationship.
We use i to represent each state ( \ (0 \ Le i \ lt 2 ^ m \) ), the i in fact corresponds to a binary number is a binary m-bit, if the j-th bit i is 1 it means the state has put a j-th character, otherwise there is no explanation to put the j-th character, then we can put the j-th character, that is to say:
by state iand character jcan be extended out of a new state i | (1<<j).
And jput in the position it is determined - we can use the function __builtin_popcount(i)to get the binary representation of i species exist how many bits to 1.
Then here I think the most important point is bothering me for a long time is a point - "How to eliminate the impact position" .
In fact, for each state iand character j, from the state if you want to itransfer to the state i | (1<<j), and we assume that ithe binary representation has c bit is 1, then we can actually find the location in which the arrangement of j is determined, it is c (also can be c + 1, depending on your initial coordinate this decision, we here assumed to be the c).
But so far we can not eliminate the influence of distance.
We can enumerate i k-bit status inside:

  • If state i k-bit is 1, then that it has been placed before the character k state i to a place (we assume \ (c_k \) ),
    so now we have to put the j in the c-th position ( for clarity, we let \ (c_j \) represents c),
    then k and j price should be \ (cnt [j] [k] \ Times (C_J - c_k) \) ; (because \ (c_k \ lt c_j \) )
  • If state i k-bit is 0, then that is not a state i k character to a place (we assume \ (c_k \) ),
    so now we have to put the j in the c-th position (for clarity we make \ (c_j \) represents c),
    then j and k cost should be \ (cnt [j] [k] \ Times (c_k - C_J) \) . (Since \ (C_J \ C_K lt \) )

So, we can see that if I had let \ (f [i] \) denote i the state minimum total consideration,
then, when our current judgment state i and character j (and we assume that the j-bit i is 0 , because at this time we can state iplus the characters jchange to a new state i | (1<<j)).
We started to open a variable \ (tmp = F [I] \) , and from 0 to m-1 traversing a character to k:

  • If k is already present in the state i, then \ (tmp - CNT = [k] [J] \ C Times \) ;
  • If k does not already exist in the state i, then \ (tmp + = CNT [k] [J] \ Times C \) . (Where c is the previous position of said character j into state i)

Why then such a position eliminates the effects?
We assume now time to put j has not put k, then our tmp variable subtracted \ (cnt [k] [j] \ Times C_J \) , then after going to put k, we will add the variable tmp on \ (cnt [k] [J] \ Times c_k \) , and \ (c_k - c_j \) is actually their distance, so one plus one minus to indirectly deal with the distance (this point puzzled me for a long time until suddenly see the light!).

Then, for each state i and j characters (j-th bit in claim state i is 0), and tmp calculated:

f[ i | (1<<j) ] = max(f[ i | (1<<j) ] , tmp);

Codes are as follows:

#include <bits/stdc++.h>
using namespace std;
int n, m, f[(1<<20)], cnt[20][20];
string s;
int main() {
    cin >> n >> m >> s;
    for (int i = 1; i < n; i ++) {
        int a = s[i-1] - 'a', b = s[i] - 'a';
        if (a != b) {
            cnt[a][b] ++;
            cnt[b][a] ++;
        }
    }
    fill(f+1, f+(1<<m), INT_MAX);
    for (int i = 0; i < (1<<m)-1; i ++) {
        int c = __builtin_popcount(i);
        for (int j = 0; j < m; j ++) {
            if ( !( i & (1<<j) ) ) {
                int tmp = f[i];
                for (int k = 0; k < m; k ++) {
                    if (i & (1<<k)) {
                        tmp += cnt[j][k] * c;
                    }
                    else { // 因为预处理cnt的时候保证cnt[x][x]==0
                        tmp -= cnt[j][k] * c;
                    }
                }
                f[ i | (1<<j) ] = min(f[i | (1<<j)], tmp);
            }
        }
    }
    cout << f[ (1<<m)-1 ] << endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/codedecision/p/11647681.html