タイトル説明
ドミノ上下二つのブロックは、各ブロックは1〜6点を有します。既存のラインアップ
上記ブロック内の点の数とS1、ブロック内の点の数として示され、S2、差それらと呼ば| S1-S2 |。例えば、図8-1において、S1 = 6 + 1 + 1 + = 9 1、S2 = 1 + 5 + 3 + 2 = 11、| S1-S2 | = 2。2つの上側および下側ブロックのスワップ位置するように各Dominoは、180°回転させることができます。ドミノは、ポイントの最小数の上下の行の間の差の回転数の最小値を使用するようにプログラムされています。
図面において、例えば、限り180°回転させる最終的なドミノとして、上下の行の差が0点であることを確認することができます。
入力形式
入力ファイルの最初の行は、正の整数n(1≤n≤1000)であるドミノドミノの数を表します。Nは、N点のドミノの次の行を表します。各行はスペースで区切られた2つの正の整数を有し、垂直ボックスは、ドミノ・ポイントを表し、Bに、及び1≤a、b≤6。
出力フォーマット
出力ファイルのみ1行は、整数が含まれています。これは、得られた回転数の最小値を表します。
サンプル入力と出力
4 6 1 1 5 1 3 1 2
1つの
分析:
この質問は実際には非常に抽象的ナップザック問題である
(あなたはバックパックがあることは私をからかっている、明らかに貪欲良いBAA(≧∇≦)テクノは??)
本当にああバックパックです!QAQは
、どのように我々はそれを調整するのですか?
我々最初のドミノは、上部の点の数が多いように、逆に、
このように点数の上方および下方ことを保証し、点の数よりも大きくなければならない。
次に、点の数が2ときフリップ乗じ上下の点の間の差である変化します!
、オブジェクトとして、ボリュームのバックパックに各ドミノを抽象の先頭の上下の点の間の違いを:このの思想は、我々は考慮に入れることができ
、我々は上に多数の点を置くことを始めとして、それぞれがフリップを入れて+1の数に。考えてみましょう:私はそれを後で後悔している場合、私は何をするかより良い、このドミノをオンにしないことが判明?その後、私はそれを元に戻すでしょう、そして、ドミノをオンに相当するものはありません。
したがって、それは-1であるターンドミノ重量の初めに、重量が入っていないドミノ1(重量ターン数に相当)
彼らはターンどんなには、上下のポイント差に影響を与えませんので、もちろん、同じドミノは、ダウンゼロ体積、重量アイテム0にあります。
この時点で、バックパックモデルが出てきました。この問題に単純化される:N項目があり、各項目のV [I]の量を考えると、その重量は1又は-1です。最小最大容積物品とケースの重量となるよう今バックパックの重量のためのベース、ボリュームTOTは、n個の物品が、バックパックに入るこれを呼び出し、TOTの全体積を超えることはできません。
ここで、DP [I] [j]はiは、最小重量jの体積にアイテムを保持することができる前面を示し
VS [i] [j]はiのjの項目ボリュームを提案するために添付のフロントを表し、
#include <iostreamの>
使用して名前空間STD;
INT N-;
INT [1005] [6005] DP; // DP [I] [j]は、i番目のアイテムバックパックの前に充填J
[1005] [6005]対BOOL ; // VS [I] [j]は、i番目のタグ物品充填Jリュック可能使用前
INT W [1005]、塩基、 TOTを; // W 格納された重量、ベースマスストレージバックパック、TOTのナップザックボリューム(初期最大差)
INTヴァル[1005]; // valの差記憶反転ドミノ各iは提供することができる
インラインINT分(INT X、Y INTを)//
{
X <Y X:?Yを返す;
}
)(INTメイン
{
; INT X、Y
N-CIN >>;
のための(INT I = 1; I <= N; I ++)
{
CIN >> X Y;
IF(X> Y)
{
ヴァル[I] = 2 *(XY) ; //もし上部自体よりも
W [I] = 1; //フリップ考慮1。
TOT = XY +; //レコードボリュームリュック
}
IF(Y> X)
{
ヴァル[I] = 2 *(YX); / /自体により大きいで
[I] = W - 1; // すなわち重量-1、元の直接等価ではない反転、逆転へ
TOT + = YX; //の体積更新
++ベース;増加//バックパックの質量
}
}
のために(INT I = 1; I <= N - 、Iは++)//ステージとして注文ドミノ
(INTのJ = 1; J <= TOT ;大プッシュするすべてのリュックサックボリュームのJ ++)//、小
{
DP [I] [J] DP = [1-I] [J]が; //前の状態を継承
対[I] [J] = VS [ I-1]〜[J]; //
(VS [I-1]〜[J-ヴァル[I IF] || J-ヴァル[I] == 0)//数iがI-1のフリップフロッから移行できるかどうか上
//ボリュームI寄与ドミノに存在するかまたはそれに等しい限り、状態を進める
場合(!VS [I] [ J])// もしDP [I] [J]に定義されていない
{//
DP [I] [J] = DP [I-1]〜[ J-VAL [I] + W [i]は; // タグが直接更新され、
VS [I] [J] = 1; //
}
他
DP [I] [J] =分(DP [I]、[J] 、DP [I-1]〜[J-VAL [I] + W [I]); // それ以外の場合、比較
DP〔から// I反転ドミノI-1 ] [J-VAL [I] ] 重量を追加し、移行
}
INT TMP;
(; I> = 1; IはTOTを= int型。I - )のため//最大容積から後方に見て、それを保証することができ最小差分値
IF(VS [N-] [I])//
{
TMP = I; //
BREAK;
}
COUT <<基地+ DP [N-] [TMP]; //ベースプラス電流を転送するのに必要な量、決定転移の現在の数から状態を変更
戻り0;
}