- 655E Codeforces дп + жадный

Тема ссылки: сравни коллапс, поэтому.

Ссылка блог: https://blog.csdn.net/kyleyoung_ymj/article/details/51628238

Бу-Ти.

Значение вопросов:

Каждый входной выборки две строки, первая строка ввода два чисел п, к, вторая входная линия строки символов, можно добавить п символы (к, представляющее строку символов диапазона после второй линии ввода, например, к = 2, то вы выбранный символ а, б, если к = 4, можно выбрать характеры а, б, в, г, являются к символам от начала символов является необязательным). Последовательности, полученные после того, как вы сделаете входную строку после того, как указанный диапазон увеличивает п максимальное число символов строки, последовательностей максимальной выходной число. Помните также включать пустую строку.

Последовательность является прерывистой.

 

 

Для справки, пожалуйста, поправьте меня неправильно.

Здесь мы предполагаем, двумерный массив с дп [I] [J] обозначает число позиций в I (I-го символа) до символа J + «а» в конце последовательности.

Итак, пусть теперь мы должны поставить символ J в г-й позиции, то мы должны обновить значение дп [я] [J] из.

Предположим, что представляет собой сумму всех дп [I-1] [J] (0 <= J <к) и, затем дп [I] [J] = (сумма + 1)% по модулю;

В это время дп [I] [J] можно разложить в дп [I-1] [J] + (сумма-дп [I-1] [J]) + 1;

Затем добавить символ после позиции I J, J приведет в конце последовательности символов добавляет (SUM-дп [я-1] [J]) + 1-й а.

На самом деле, не все в конце J символов последовательности плюс 1, почему так много, чтобы увеличить его? ?

Пусть пример, теперь за увеличением строки символов aabac а, перед добавлением символов а, мы имеем следующую последовательность

Концевой: а, аа, ба, ааа , ABA, AABA; 

окончание Ь: B, AB, AAB; 

окончание с: с, ас, Ьс, ААС , ABC, BAC, AAAC, AABC, ДКС , aabac;

 

Ну, теперь мы должны добавить в задней части символа «а», а до этого, мы можем также предоставить все последовательности затем следовать выше классификации к другой, чтобы организовать его снова (плюс пустая строка):

1 . Конг цюань, а, аа, ааа,
 2 .b, ба
 3 аб, ABA
 4 AAB, AABA
 5 с
 6 .ac The
 7 Ьс
 8 ААС
 9 ! .Abc
 10 BAC
 11 AAAC
 12 AABC
 13 ДКС
 14 aabac

В передней части каждой строки строки символов в данном документе после увеличения символа «а» становится строкой позади, то есть за фронтом строки является строкой префикса.

То есть, после того, как все , кроме последней строки каждой строки (последовательности) ------ >> увеличивается после того, как персонаж будет приводить к концу подпоследовательности увеличивается на 1, все подпоследовательности перед плюс характер полученная последовательность действительно имела место, то есть, было вычислено в дп [I-1] [J ] в не потому , что позиция символа после увеличения я принести. Каждая строка выше будет только добавить новую подпоследовательность . Теперь мы смотрим на него в смелом выше четырех линий, четыре строки первой подпоследовательности либо не заканчиваются символами а, или пустая строка (первая строка «пустая строка» слово ...... ), то мы не можем использовать первый суб-последовательность , чтобы заменить целые последовательности строк, можно сказать , с первой подпоследовательностью каждой строки вместо последней последовательности линии , поэтому мы удалили все Влияние подпоследовательности довести до конца, но это не влияет на преобразование для всех символов в последовательности , чтобы довести до конца, конечно, дополнительно содержит пустую строку. Выше линии 14, после добавления строки символов за aabac, увеличение на 14 суб-последовательности.

所以 дп [I] [J] = дп [I-1] [J] + (сумма-дп [I-1] [J]) + 1.

После вычисления дп [I] [J], на этот раз должна быть обновлена ​​сумма в самом деле, так как дп [I-1] [J] становится дп [I] [J]

此时 сумма = (сумма-дп [I-1] [J] + дп [I] [J]) = сумма-дп [I-1] [J] + (сумма + 1) = 2 * сумма-дп [ I-1] [J] + 1;

Добавим символ J во времени, для того, чтобы максимальное значение суммы, мы определенно должны выбрать дп [я-1] [J] минимальное значение этого, это как спрашивать жадный ...

И, наконец, строка была дана, мы непосредственно рассчитаны с использованием вышеприведенной формуле может быть, и в конце строки из п символов должно быть увеличено, мы обнаружили, каждый раз, когда символ J, то дп [I-1] значение [J] сведен к минимуму в соответствии с приведенной выше формулой, так что сумма может храниться максимум, а затем в связи с модулем, поэтому мы не можем непосредственно сравнить размер, но следует записать символ «а» на символ «а» + к положение последнего вхождения каждого символа, найти позицию символа, который сводит к минимуму появление строки добавляется к концу, потому что место, безусловно, является наименьшим из наименьшего значения.

Код (чтобы стать одномерным):

#include <iostream> 
#include <CString> 
#include <алгоритм> 
#include <очереди> 
#include <карта> 
#include <стек> 
#include <CMATH> 
#include <вектор> 
#include < набор > 
#include <cstdio> 
# include < строка > 
#include <Deque> 
 с использованием  пространства имен STD; 
определение типа во долго  долго LL;
 = 1E9 + MOD 7. ; 
Л.Л. н-, м, K, T, 
символ УЛ [MAXN]; 
LL ДП [ 26 ]; // сохранить в конце каждого суб-последовательности числа символов 
Int Последнее [ 26 ]; // сохранить каждый положение последнего символа отображается 
Int Main () 
{ 
    Scanf ( " % LLD% LLD " , & п, & к); 
    Scanf ( " % S " , СИЛ + 1. ); 
    MemSet (последний, 0 , в SizeOf (последний));
     INT Len StrLen = (+ СТР 1. ); 
    LL СУММА = 0 ;
     для( Int I = 1. , I <= Len; I ++) { // обрабатывать входную строку 
        INT ID = STR [I] - ' A ' ; 
        Last [ID] = I; // обновляет последнее вхождение 
        будет предварительно = DP [ID]; // позиция 1-я дп , когда [ID] временно сохраняется в 
        DP [ID] = (SUM + 1. + MOD) MOD%; // обновление DP [ID] 
        СУММА = (SUM пред + DP [ID] + MOD) MOD%; // обновление СУММА 
    }
     для ( INT I = 1. , я <= п; я ++) { // увеличение п для заданного диапазона символа 
        INT Min = INF; // находим наименьшее положение 
        INT указанное выше идентификатор;// хранится положение минимального символа 
        для ( Int J = 0 , J <K; j ++ ) {
             ЕСЛИ (Последнее [J] < Мин) { 
                Мин = Последнее [Дж]; 
                ID = J; 
            } 
        } 
        Последнее [ID] = I Len +; // обновить последнее вхождение в большой позиции 
        LL предварительно DP = [ID]; // позиция I-1 дп , когда [ID] временно сохраняется в 
        DP [ID] = (SUM + 1. + MOD) MOD%; // обновление ДП [ID] 
        СУММА = (SUM + предварительно ДП [ID] + MOD * 2 )% MOD; // обновление СУММА 
    } 
    на Е ( "ДНУ% \ n- " , SUM + 1 ); // конечный результат плюс 1, потому что есть пустая строка 
    возврат  0 ; 
}

 

рекомендация

отwww.cnblogs.com/6262369sss/p/11986388.html