質問A:真央Yichen / $牛$ $の部分集合$
制限時間:1秒 メモリ制限:512メガバイト
フェイス質問
彼は公に質問に直面して減少しました。
問題の解決策
タイトルは大きな神のように見えますか??それは質問が、その後死亡した記号のように見えます。
まず、明らかに$ O(3 ^ n)の$アルゴリズム。明らかに、また$ 20個の$のテストポイントのための生活を困難にします。
正解は$ $ $ $ $真ん中のアルゴリズムで$会うの$の$でよく知られています。あなたは40未満で$ $で$ $ $ $ $途中のデータを満たす$使用することができますか??
2年半のパスのために、私たちは一緒に入れて、2人の男性が同じスコアを取得することを条件に、正当な答えを構成することができます。
だから、よりインテリジェントなアプローチは、二人それぞれがポイントの数を取得し記録することはありませんが、2つの貧しいレコードを獲得しています。
カットについては、誰が誰にフリップうまく同じ言葉を重要ではありません。重複を避けるため、逆に従事しません。
だから我々は数をマッピングした経路差の前半のそれぞれに対して、$マップ$を開きます。そして、として、添え字の前半は、ステート・ストレージ、簡単なスプライシングを総なめにしました。
クエリ内の$マップ$の違いによる走行軌跡の後半では、あなたが戦うために持っている、状態が設定します。
コード:
#include <ビット/ STDC ++ H> の#define RINTレジスタINT 使用して 名前空間STDを、 int型のn、[ 23 ]、TOT、ANS。 BOOL VIS [(1 << 21)+ 5 ]。 地図 < INT、INT > M。 ベクター < INT > V [ 10000005 ]。 インラインボイドDFS1(RINT kを、RINTのRES、RINTコン) { もし(K == N / 2 + 1 ) { 場合(m.find(RES)== m.end())M [RES] = ++ TOT ; INT LINは= M [RES]を、V [LIN] .push_back(CON)。 返します。 } DFS1(K + 1 、RES、CON)。 DFS1(K + 1、RES + [K]、CON |(1 << K- 1 ))。 DFS1(K + 1、RES-[K]、CON |(1 << K- 1 ))。 返します。 } インラインボイドDFS2(RINT kを、RINT RES、RINTコン) { もし(K == N + 1 ) { 場合(m.find(RES)!= m.end()) { int型 LIN =M [RES]。 用(RINT I = 0 ; I <V [LIN] .size(); ++ I) VIS [V [LIN] [I] | CON] = 1 。 } を返します。 } DFS2(K + 1 、RES、CON)。 DFS2(K + 1、RES-[K]、CON |(1 << K- 1 ))。 DFS2(K + 1、RES + [K]、CON |(1 << K- 1 ))。 返します。 } int型のmain() { scanf関数(" %d個"、&N); 用(RINT I = 1 ; I <= N; ++ I)のscanf(" %dの"、および[I])。 DFS1(1、0、0); DFS2(N / 2 + 1、0、0 ); 用(RINT i = 1 ; iが=(< 1個の << N) - 1 ; ++ I)ANS + = VIS [I]。 printf(" %d個の\ n " 、ANS)。 リターン 0 ; }