CodeForces - 655E dp + greedy

Topic links: cf collapse, so.

Reference blog: https://blog.csdn.net/kyleyoung_ymj/article/details/51628238

Bu Ti.

Meaning of the questions:

Each sample input two lines, the first line of the input two numbers n, k, a second input line of a character string, you can add n characters (k representing the character string of the range after the second line of input, such as k = 2, then you have selected character a, b; if k = 4, you can select the characters are a, b, c, d, is a k characters from the beginning characters is optional). Sequences obtained after you make the input string after the specified range increases the n maximum number of characters of the string, the maximum output number sequences. Remember also include an empty string.

Sequence is discontinuous.

 

 

For reference only, please correct me wrong.

Here we assume a two-dimensional array with dp [i] [j] denotes the number of positions to the i (the i-th character) up to the character j + 'a' at the end of the sequence.

So suppose now we have to put a character j in the i-th position, then we should update the value of dp [i] [j] of.

Suppose represents the sum of all dp [i-1] [j] (0 <= j <k) and, then dp [i] [j] = (sum + 1)% mod;

At this time dp [i] [j] can be decomposed as dp [i-1] [j] + (sum-dp [i-1] [j]) + 1;

Then add character after the position i j, j will result in the end of the sequence of characters adds (sum-dp [i-1] [j]) + 1 th a.

In fact, not all at the end of the number sequence j characters plus 1, why is so much to increase it? ?

Let an example, now behind the increase a character string aabac a, before adding the characters a, we have the following sequence

The a end: a, aa, ba, aaa , aba, aaba; 

ending of b: b, ab, aab; 

ending of c: c, ac, bc, aac , abc, bac, aaac, aabc, abac , aabac;

 

Well, now we have to add in the back of a character 'a', and before that, we may as well give all sequences then follow the above classification to another to arrange it again (plus a null string):

1 . Kong chuan, a, aa, aaa,
 2 .b, ba
 3 ab, aba
 4 aab, aaba
 5 c
 6 .ac The
 7 bc
 8 aac
 9 ! .Abc
 10 bac
 11 aaac
 12 aabc
 13 abac
 14 aabac

In front of each line of the character string herein after increasing the character 'a' becomes a string behind, that is to say behind the front of the string is a prefix string.

That is, after all but the last of a string of each line (sequence) ------ >> it increases after a character will lead to the end of a subsequence increased by 1, all sub-sequences in front of a plus character the resulting sequence has actually occurred, i.e., it has been calculated in the dp [i-1] [j ] in a, not because a character position after increasing i bring. Each line above will only add a new sub-sequence . Now we look at it in bold above four lines, four lines of this first subsequence either not end with the characters a, or is an empty string (the first line of "empty string" word ...... ), then we can not use the first sub-sequence to replace the entire line sequences, it can be said with the first sub-sequence of each line instead of the last sequence of the line , so we removed all to Effect of a subsequence bring the end, but it does not affect the conversion for all the characters in a sequence to bring the end, of course, further comprising an empty string. The above line 14, after adding a character string behind a aabac, the increase is 14 sub-sequences.

所以dp[i][j]=dp[i-1][j]+(sum-dp[i-1][j])+1。

After computing dp [i] [j], this time should be updated sum in fact, because dp [i-1] [j] becomes dp [i] [j]

此时 sum=(sum-dp[i-1][j]+dp[i][j])=sum-dp[i-1][j]+(sum+1)=2*sum-dp[i-1][j]+1;

We add character j in time, in order to make the maximum value of the sum, we definitely have to pick a dp [i-1] [j] is the minimum value of it, this is like asking greedy ...

Finally, the string has been given, we directly calculated using the above formula can be, and for the end of the string of n characters to be increased, we have found each time a character j, it dp [i-1] value [j] is minimized according to the above formula so that the sum can be kept maximum, and then due to the modulus, so we can not directly compare the size, but should record the character 'a' to the character 'a' + k the position of the last occurrence of each character, find the character position that minimizes the emergence of a string is added to the end, because the location is certainly the smallest of the smallest value.

Code (to become a one-dimensional):

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<set>
#include<cstdio>
#include<string>
#include<deque> 
using namespace std;
typedef long long ll;
#define eps 1e-8
#define INF 0x3f3f3f3f
#define maxn 2000005
const int= 1E9 + MOD . 7 ; 
LL n-, m, K, T; 
char STR [MAXN]; 
LL DP [ 26 is ]; // save the end of each sub-sequence number of character 
int Last [ 26 is ]; // save each position of the last character appears 
int main () 
{ 
    Scanf ( " % LLD% LLD " , & n-, & K); 
    Scanf ( " % S " , STR + . 1 ); 
    Memset (last, 0 , the sizeof (last));
     int len strlen = (+ STR . 1 ); 
    LL SUM = 0 ;
     for( Int I = . 1 ; I <= len; I ++) { // process the input string 
        int ID = STR [I] - ' A ' ; 
        Last [ID] = I; // updates last occurrence 
        ll pre = DP [id]; // the position i-1 dp when [id] is temporarily stored at 
        DP [id] = (SUM + . 1 + MOD) MOD%; // update DP [id] 
        SUM = (SUM pre-+ DP [ID] + MOD) MOD%; // update SUM 
    }
     for ( int I = . 1 ; I <= n; I ++) { // increase of n for a given range of character 
        int Min = INF; // find the smallest position 
        int the above mentioned id;// stored position of the minimum character 
        for ( int J = 0 ; J <K; J ++ ) {
             IF (Last [J] < Min) { 
                Min = Last [J]; 
                ID = J; 
            } 
        } 
        Last [ID] = I len +; // update the last occurrence of the large position 
        LL pre DP = [id]; // the position i-1 dp when [id] is temporarily stored at 
        DP [id] = (SUM + . 1 + MOD) MOD%; // update DP [ID] 
        SUM = (SUM + pre-DP [ID] + MOD * 2 )% MOD; // update SUM 
    } 
    the printf ( "LLD% \ n- " , SUM + 1 ); // final result plus 1, because there is an empty string 
    return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/6262369sss/p/11986388.html