https://vjudge.net/problem/CodeForces-132C
質問の意味: Fが前進を表し、Tは後方ターンを表し行くためにどこまで依頼するまで、私たちは、文字N回を修正する機会を持っています
考え [j] [i]はDP: [D] i番目の文字の前に、j番目の修飾を表す、長さkを行く、dは現在の状態に向かって最大の長さであります
したがって、分割することができる再帰的な関係は、i番目の文字「F」または「T」は
そして、多次元再発DPは電流iで、jは古いI、Jの再帰的なアウトからのもの、すなわち、I-1、jkが、実際には、暴力のメモリです。
注:全体的な話の、我々は最初の-INFに初期化し、すべての後、[0] [0] [1]、DP DP [0] [0] [0]を0に初期化されますが、また、jに注意を払わなければならない最大を使用してk個の列挙0からnまで、J。
書式#include <iostreamの> の#include <cstdioを> する#include < 文字列 > の#include <CStringの> の#include <ベクトル> の#include <cmath> の#include <キュー> の#include <スタック> の#include <マップ> 書式#include < 設定 > 書式#include <アルゴリズム> 使用して 名前空間はstdを、 CONST INT MAXN = 110 。 const int型 INF = 0x3f3f3f3f 。 チャーS [MAXN]。 int型のn; 110 ] [ 55 ] [ 2 ]; //はビットI jの動作は、現在の状態の前後方向(0正1負)を表す int型のmain(){ scanfの(" %のS "、S + 1 ); scanfの(" %D "&N-); INT LEN = STRLEN(S用+ 1 ) のために(int型 I = 0 Iは= LEN <; I ++は){ ため(INT J = 0 ; J <= N; J ++ ){ DP [I] [ J] [ 1 ] DP = [I] [J] [ 0 ] = - INF。 } } DP [ 0 ] [ 0 ] [ 1。 DP = [] 0 ] [ 0 ] [ 0 ] = 0 ; // 初期化及びj、順番に全体的な話のkに注意深く循環 // 暴力の記憶 のために(INT I = 1。 ;私は= LEN <; Iは++ ){ ため(INT J = 0 ; J <= N; J ++){ // j番目の操作は、I-1ビット前フロントJK操作(前)再発が来る ため(INT K = 0 ; K <= J、K ++){ // 選択分配 IF(S [I] == ' T' ){ IF(K&1){ // 多次元DP、I、J再帰処理類似考え DP [I] [J] [ 0 ] = MAX(DP [I] [J] [ 0 ]、DP [I- 1 ] [JK] [ 0 ] + 1 ); [DP [I] [J] 。1 ] [= MAX(DP [I] [J] 。1 ] [I-、DP 1 ] [JK] [ 1 ] - 。1 ); } 他{ DP [I] [J] [ 0 ] = MAX(DP [I] [J] [ 0 ]、DP [I- 1] [JK] [ 1]); DP [I] [J] [ 1 ] = MAX(DP [I] [J] [ 1 ]、DP [I- 1 ] [JK] [ 0 ])。 } } 他{ 場合(K&1 ){ DP [I] [J] [ 0 ] = MAX(DP [I] [J] [ 0 ]、DP [I- 1 ] [JK] [ 1 ])。 DP [I] [J] [ 1 ] = MAX(DP [I] [J] [ 1 ]、DP [I- 1 ] [JK] [ 0 ])。 } 他{ DP [I] [J] [ 0 ] = MAX(DP [I] [J] [ 0 ]、DP [I- 1 ] [JK] [ 0 ] + 1 )。 DP [I] [J] [ 1 ] = MAX(DP [I] [J] [ 1 ]、DP [I- 1 ] [JK] [ 1 ] - 1 )。 } } } } } のprintf(" %d個の\ n "、MAX(DP [LEN] [N] [ 0 ]、DP [LEN] [N] [ 1 ]))。 リターン 0 ; }