ギフト(半分プラス2ウェイDFS)

トピックリンク

質問の意味:nはあなたの現在の重量を与えるが、あなたは体重Mの贈り物を動かす一回よりも多くを見ていない、あなたはMパワーを与えます。

アイデア:バックパックには思えるが、Mあまりにも。したがって、DFSを使用して、Nも45、最初の検索DFSは、ケースの最初の半分の重量の全てが満たさ検討し、次に重量双方向ように、次いでさらに後半、半回答を検索します。

書式#include <cstdioを> 
する#include <CStringの> 
の#include <アルゴリズム> 
書式#include <ベクトル> 
の#include <マップ> 
書式#include <キュー>
 の#defineは長い長いでしょ
 使用して 名前空間はstdを、
CONSTの INT MAXN =(1 << 24)+ 10 
LL N、M。
LL [MAXN]、B [MAXN]。
LL K; 
ANS LL; 
ブールCMP(LLのB、LL)
{ 
    戻り > Bと、
} 
(LL和)を見つけるllの
{ 
//     のprintf( "M-合計:%LLDする\ n"、M-合計)。
    int型のy =K;
    もし(B [Y]> M- 和)
        Y = UPPER_BOUND(B + 1、B + 1 + K、M-和)-B- 1 // のprintf( "Y:%Dを\ n"、Y); 
    ANS = MAX(ANS、B [Y] + 和)。
} 
INT DFS(INT X、LLの合計)
{ 
    場合(X ==(N / 2 + 2)+ 1 
    { 
        B [ ++ K] = 和。
        リターン 1 ; 
    } 
    DFS(X + 1 、合計)。
    もし(和+ [X] <= M)
    DFS(X+ 1、和+ [X])。
} 
INT DFS2(INT X、LLの合計)
{ 
    場合(X == N + 1 
    { 
        (和)を見つけます。
        リターン 1 ; 
    } 
    DFS2(X + 1 、合計)。
    もし(和+ [X] <= M)
    DFS2(X + 1、和+ [X])。
} 
int型のmain()
{ 
    scanf関数(" %のLLDの%のLLD "、&​​M、&N)
    int型 iは= 1、I ++; iが<= N。
    { 
        scanf関数(" %のLLD "、および[I])。
    } 
    ソート(A + 1、A + N + 1 、CMP)。
    DFS(10 ); 
    ソート(B + 1、B + K + 1 )。
    K =一意(B + 1、B + K + 1) - (B + 1 )。
    DFS2(N / 2 + 30 ); 
    printf(" %LLDする\ n " 、ANS)。
    
    
 }

 

おすすめ

転載: www.cnblogs.com/2462478392Lee/p/11291391.html