マジックボールの問題(ネットワークフロー24個の質問)

問題の説明:

次の規則は、今順番に番号1,2,3、...ボールにn列をYaoanされ、n個の列があるとします。

(1)あなただけの柱の上部にボールを置くことができます。

(2)同じ列に、任意の2個の隣接するボールが完全正方形の数の合計です。

ボールの最大数はn列の上に置くことができる計算するアルゴリズムを設計するようにしてください。例えば、4つの列に11球を保持することができます。

<<プログラミングタスク:

所与のnについて、ボールの最大数を計算するN列に置くことができます。

4 <= N <= 55

問題の解決策

単球が重要ではなく、決意が下に設置いくつかのカラムを必要とするボールに添加することができる場合、列数の増加を考慮すると、増加します。

各ボールは大から小側にも一度だけ確保するために接続されたエッジの数の正方形の周りに互いへの2個のボールが接続され、二つの点に分割しました。

質問は、次に最小のパスカバレッジとなり、パスの数は列の数です。

M個のボール列挙、答えのようなトラバースのパスからの出力にプログラムするように、数m-1カラムよりも大きいパスの数。

タイムアウトしないようにするために、我々は新しいボールを追加し、パスを増大させるから、一度ボールを走った理由を大から小にもエッジにある、ことができます。

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、

const  int型 MAXN = 3605 ;
INTのN、M。
int型VIS [MAXN]、試合[MAXN]、タイマー。
BOOL正方形[MAXN << 1 ]。
ベクター < INT > E [MAXN]。

ボイドのinit(){ 
  タイマ = 0 
  memset(一致、0はsizeof (一致))。
  memsetの(VIS、0はsizeof (VIS))。
} 

BOOL DFS(INT U){
   場合(VIS [U] ==タイマー)返す ; 
  VIS [U] = タイマー。
  (符号なし整数 = I 0 ; iは<E [U] .size(); iは++ ){
     int型、V = E [U] [I]。
    もし(!一致[V] || DFS(一致[V])){ 
      一致[V] = U。
      返す ; 
    } 
  } 
  を返す 
} 

ボイド GETINT U){ 
  のprintf(" %dの" 、U)。
  VIS [U] = タイマー。
  もし(![一致U +1800 ]){のputchar(10)。返す;}
   得る(一致[U + 1800 ])。
} 

ボイドプリント(){
   ++ タイマー。
  以下のためにint型 I = 1 ; iがm <I ++のがもし(!VIS [i]を=タイマー)を取得(I); 
} 

int型のmain(){
   ためint型 i = 1 ; iは= <* 7200 ; iは++ 
   正方形[iが * I] = 
  scanf関数(" %のD "、&N)
  int型ANS = 0 ;
  一方、(++ {M)
     のためのint型 iは= 1 ;私がm <I ++の場合(正方形[iがmを+])E [M] .push_back(I + 1800 )。
    ++ タイマー;
    もし(DFS(M))ANS ++ もし(M-ANS> N){のprintf(" %d個の\ n "、M- 1)、印刷();出口(0 );} 
  } 
}
コードの表示

 そこ貪欲法、置く、または新しくオープンした(正しさを知らない)に柱が置くことができます。

一見、法律2 + 2 + 4 + 4 + 6 + 6 +ボールの数があります....

おすすめ

転載: www.cnblogs.com/sto324/p/11334014.html