質問表面:https://www.cnblogs.com/Juve/articles/11615883.html
国X陸軍:
O(T * N)直接貪欲な慣行を持っているようです
実際には、ログの半分以上を超えることができます
BA降順ですべての位置の最初の(このプログラムの後、ソート順序は、最適なスイープです)
答えのその後の半分
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> に#define int型、長い長い 再登録の#define std名前空間を使用しました。 const int型MAXN = 1E5 + 5。 インラインint型リード(){ 再int型のx = 0;再チャーCH = GETCHAR()。 一方、(CH < '0' || CH> '9')CH = GETCHAR()。 (CH> = '0' && CH <= '9'){X =(x << 3)+(X << 1)+ CH-'0' 、CH = GETCHAR();}ながら 戻りX。 } int型、T、N、L、R。 構造体ノード{ int型、B。 インラインフレンドブール演算子<(ノードP、ノードq){ 戻りPB-PA> QB-QA。 } } [MAXN] C。 (再INT X){インラインBOOLチェック (REは、I = 1 int型のために、 I <= N; ++ I){ X - = C [i]は.A。 } 1を返します。 } (){主署名された T =を読み取ります()。 { - (T)一方 、)N =(読み取り L = 0、R = 0。 (; iは<= N;再I = 1 INT I ++)のために{ C [i]は.A読み取り=()、C [i]は.B = read()は、 L + = C [i]は.A、R + = C [i]は.B。 } ソート(C + 1、C + N + 1)。 (L <R){ながら 再INT半ば=(L + R)>> 1。 (チェック(MID))、R =半ばであれば、 他リットル=ミッド+ 1; } のprintf( "%LLDする\ n"、L)。 } 0を返します。 }
順列:
$ C_ {N} ^ {I} * C_ {N} ^ {I} {N} ^ {I} $ C_ * C_ {N} ^ {NI} $に$、
この場合、そのプログラム番号の選択されたn(NI)のi番目で選択されたプログラムのn個の数のうち、各iについて、であり、最後に加算します。
そのような回答は、実際には、得られた物品の2Nに等しい、選択された最初のNI、N(NI)番目の後に選択され,,
iは0からnまでのすべての整数上で動作するため、また、その後、蓄積されたプログラムの数は$ C_ {2 * N} ^ {N} $に等しいです。
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> に#define int型、長い長い 再登録の#define std名前空間を使用しました。 const int型MAXN = 2E6 + 5。 const int型MOD = 1E9 + 7。 int型、T、N、FAC [MAXN]、[MAXN] INV。 インラインINT q_pow {(再int型のB、再INT P INT RE) 再INT RES = 1。 一方、(B){ IF(B&1)RES =のRES *%のP。 = A *%pを。 B >> = 1。 } RESを返します。 } (INT N RE)インラインボイドget_c { FAC [0] = FAC [1] = INVを[0] = 1。 用(RE I = 2 INT; iは= Nを<; ++ i)が{ FAC [i]は= FAC [I-1] * I%MOD。 } INV [N] = q_pow(FAC [N]、MOD-2、MOD)。 { - (I; I> = 1再I = N-1の整数)のために INV [I] = INV [I + 1] *(I + 1)%のMOD。 } } インラインINT C(RE INT nは、再int型のM){ IF(M> N)戻り0; IF(M == n)がリターン1。 FAC [N]%MOD * INV [M]%MOD * INV [nm]の%MODを返します。 } メイン(){署名さ get_c(2E6)を、 scanf関数( "%のLLD"、&T)。 { - (T)一方 、scanf関数( "%のLLD"、&N) printf( "%LLDする\ n"、C(2 * N、N))。 } 0を返します。 }
回文:
:Gの定義[I] [j]は、j個のパリンドロームに私このセクションでは、G [I + 1] [J-1]の転送を形成することができるかどうかを示します
以下のために(; iは= LEN <; I = int型1 ++ I){ G [i]は[I] = 1。 F [i]は[I] = 1。 (INT J = 1; J <=分(I-1、lenの-I); ++ j)のために{ 場合(S [IJ] == S [iがjは+]){ Gは[IJ] [iがjで+ ] = 1。 }他にブレーク。 } } のために(INT I = 1; I <= lenの-1; ++ I){ IF(S [I] == S [I + 1]){ G [i]は[I + 1] = 1。 F [i]は[I + 1] = 3; (INT J = 1; J <=分(I-1は、lenの-I-1); ++ j)のための{ IF(S [IJ] == S [I + 1 + J]){ G [IJ] [I + 1 + j] = 1。 }他にブレーク。 } } }
F [i] [j]の定義は、j個の答えに私を意味し、この
有转移:$ Fの[1] [R] = F [L + 1] [R] + F [L] [R-1] -f [L + 1] [R-1] + G [L] [R ] $
書式#include <iostreamの> の#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> に#define int型、長い長い 再登録の#define std名前空間を使用しました。 const int型MAXN = 5005; チャーS [MAXN]。 int型のT、LEN、[MAXN] [MAXN] F。 BOOL G [MAXN] [MAXN]。 署名されたメイン(){ scanf関数( "%sの"、S + 1)。 LEN = strlenを(S + 1)。 以下のために(; iは= LEN <; I = int型1 ++ I){ G [i]は[I] = 1。 F [i]は[I] = 1。 (INT J = 1; J <=分(I-1、lenの-I); ++ j)のために{ 場合(S [IJ] == S [iがjは+]){ Gは[IJ] [iがjで+ ] = 1。 }他にブレーク。 } } のために(INT I = 1; I <= lenの-1; ++ I){ IF(S [I] == S [I + 1]){ G [i]は[I + 1] = 1。 F [i]は[I + 1] = 3; (INT J = 1; J <=分(I-1は、lenの-I-1); ++ j)のための{ IF(S [IJ] == S [I + 1 + J]){ G [IJ] [I + 1 + j] = 1。 }他にブレーク。 } } } {(; iが= LEN <++ iはi = 2 INT)のための (int型、L = 1、L <= LEN-I + 1; ++ L)は{ I-1 INT R = 1 +。 F [L] [R] = F [L + 1] [R] + F [L] [R-1] -f [L + 1] [R-1] + G [L] [R]。 } } のscanf( "%のLLD"、&T)。 { - (T)一方 、R、int型のL再 scanf関数( "%のLLDの%のLLD"、&L&R)。 printf( "%LLDする\ n"、F [L] [R])。 } 0を返します。 }