2019頭の牛オフより学校第七Hペア桁DP

イタリアということ:3はあなたにA、Bの数を与えるために、Cは尋ねたペア(i、j)は、1 <= I <= A、1 <= J <= B、iとj> CまたはI XOR、jの何<C。、B、Cの範囲1E9。

アイデア:場の方程式を推進している表情を加えたものを無駄に、画面を行います。後に、これはデジタルDP(コード高齢者の次の行からORZ)であることを知っています。まず第一に、我々は問題を入れて、IとJ <Cと私のXOR j>は番号のC数、総数(* B)を減算することにより、この数最小限に抑えることができます。私たちは、DP、いくつかのプロセス変数を設定します。OK1、iとjビットは以前に満たされたが、iとj <C、OK2共感を満たされています。LIM1は、私は簡単に、LIM2共感を埋めることができるかどうかを示します。ZERO1ビットが全て0、ZERO2共感上記フィルか否かを示します。DPときに、ライン上の検索のメモリ。DPは非常に直感的なプロセスが説明されていません。(私はそうほとんどの位置DPの舞台に考えて、あまりにも料理QAQ書きました)

コード:

#include <ビット/ STDC ++ Hが> 
の#define LL長い長い
名前空間stdを使用。
const int型MAXN = 55; 
【MAXN] INT [MAXN] B、[MAXN] C。
LL DP [MAXN] [2] [2] [2] [2] [2] [2]。
LL DFS(INT DEP、OK1 BOOL、OK2ブール、ブール値LIM1、ブール値LIM2、ブールZERO1、BOOL ZERO2){ 
	IF(DEP == -1){ 
		リターン(ZERO1 == 0 && ZERO2 == 0)。
	} 
	(DP [DEP] [OK1] [OK2] [LIM1] [LIM2] [ZERO1] [ZERO2]!= -1){場合
		[DEP] [OK1] [OK2] [LIM1] [LIM2] [ZERO1 DP返します] [ZERO2]。
	} 
	int型MX1、MX2。
	(LIM1)MX1なら= [DEP]。
	他MX1 = 1; 
	IF(LIM2)MX2 = B [DEP]。
	他のMX2 = 1; 
	LL ANS = 0。
	以下のために(INT i = 0; iは= MX1を<; iは++){ 
		ための(int型J = 0であり、j <= MX2あり、j ++){
			(もし!OK1 &&((I&J)>)[DEP] C)続けます。
			(もし!OK2 &&((I ^ J)<)[DEP] C)続けます。
			ANS + = DFS(DEP - 1、OK1 ||((I&J)<)[DEP] C、
			OK2 ||((I ^ J)> [DEP] C)、LIM1 &&(I == MX1)
			(J == MX2 && LIM2)、ZERO1 &&(I == 0)、ZERO2 &&(j == 0))。
		} 
	} 
	DP [DEP] [OK1] [OK2] [LIM1] [LIM2] [ZERO1] [ZERO2] = ANS。
	ANSを返します。
} 
(LL A、LL B、LL C){解決LL 
	LLのRES = * Bを、
	memset(0、はsizeof(a)参照)。
	memset(B、0、はsizeof(b)参照)。
	memset(C、0、はsizeof(c)参照)。
	memsetの(DP、-1、はsizeof(DP))。
	以下のために(INT i = 0; iは<= 35; I ++){ 
		[I] = A&1。A >> = 1。
		B [I] = B&1。B> > = 1。
		C [I] = C&1。C >> = 1。
	} 
	戻りRES - DFS(35、0、0、1、1、1、1)。
} 
int型のmain(){ 
	int型のT。
	LL A、B、C。
	scanf関数( "%のD"、&T)。
	(T--){一方
		のscanf( "%LLD%LLD%LLD"、&A、&B、&C)。
		printf( "%LLDする\ n"、(A、B、C)を解きます)。
	} 
}

  

おすすめ

転載: www.cnblogs.com/pkgunboat/p/11324586.html