トピック:https://www.luogu.org/problemnew/show/P2577
質問の意味:nは誰もが個人的なDafan時間と夕食の時間を持って、彼らは2つのチームに分けられます。すぐにヒットご飯の後に誰もが食べます。あなたが食べるために最短時間の全体的な手配を行うことができるか尋ねてください。
アイデアは:まず、欲はまだ良いと思うです。合計時間は、実際には、最新の期間の+ Dafanの終わりを食べる時間でチームを食べます。
夕食後、チームの前にいる人たち、彼らは合計時間、キューイング時間を超えていない場合は、それらを考慮する必要はありません。配置された場合は、時間をキューイングのチームは、固定されています。配列の順序で、それは問題ではありません。
だから我々は前方に置く食べるために長い時間を取る必要があります。夕食のための待ち時間ので、しかし、時間の順序は順序の影響を受けている影響を与えません。
その後、我々は2つのチームに分かれ、それらを与える方法を検討することができます。
まず、私は、アカウントに個人を取っ$最初の$を表す[I] [J] [K] $ $ DPを検討し、初めてのチームのラインアップは、第2チームは$ K $、すべての最初が食べる時にキューイングされたの$ jは$です食事の時間を終了します。
しかし、我々はその$ jの$を発見し、$ K $二つのチームが時間をキューイング合計すると、固定されているので関係が存在します。だから我々は、キュー時間とを維持するために$和[i]は$接頭辞を使用することができます。あなたはの寸法を小さくすることができます。
だから我々は$私は、アカウントに個人を取っ$最初の$を表す$ DP [i]の[j]を使用することができ、最初のチームのラインアップは、$ jは$初めて、すべての食事の時間です。jは$ - このとき、第2チームは明らかに時間がキューイングされると、[i]は$和であります
そして、DPが$ [I] [J] =分(MAX(DP [I-1]〜[J-取得[I]]、J +食べ[i])と、最大(DP [I - 1] [j]は、合計[I] - jは+食べ[i])と)$ $ I $は第二位、個人やチームの最初のチームの最初の行を表します。
1の#include <cstdioを> 2の#include <cstdlib> 3の#include <地図> 4の#include < 設定 > 5の#include <CStringの> 6の#include <アルゴリズム> 7の#include <ベクトル> 8の#include <cmath> 9# <積層体>含む 10の#include <キュー> 11の#include <iostreamの> 12 13 の#define INF 0x3f3f3f3f 14 使って 名前空間STDを、 15 typedefの長い 長いLL。 16のtypedefペア< int型、int型 > PR。 17 18 INT N。 19 のconst int型 MAXN = 205 ; 20 構造体ノード{ 21 INTが 取得食べます。 22 } STU [MAXN]。 23 INTの和[MAXN]。 24 INT DP [MAXN] [MAXN * MAXN * 2 ]。 25 26 ブールCMP(ノードA、ノードB) 27 { 28 リターン a.eat> b.eat。 29 } 30 31 のint main()の 32 { 33 scanf関数(" %のD "、&N) 34 のmemset(DP、0x3fを、はsizeof (DP))。 35 のために(int型 I = 1を iが++; iが<= N ){ 36 (scanf関数" %d個の%のD "、&STU [I]。得る、および[I] .eat STU)。 37 } 38 ソート(STU + 1、STU + 1 + N、CMP)。 39 40 のために(int型 i = 1 ; iが<= N iが++ ){ 41 和[I] =和[I - 1 ] + STU [I]。取得; 42 } 43 DPは[ 0 ] [ 0 ] = 0 。 44 のために(int型 i = 1 ; iが<= N; iが++ ){ 45 のために(INT J = 0 ; J <=和[I]; J ++ ){ 46 であれば(J> = STU [i]を得る)DP [ I] [J] =分(DP [I]、[J]、MAX(DP [I - 1 ] [J - STU [I] を取得 ]、J + STU [I] .eat))。 47 DP [I] [J] =分(DPは[I] [J]、MAX(DP [I - 1] [J]、和[I] - J + STU [I] .eat))。 48 } 49 } 50 51 INT ANS = INF。 52 のために(INT J = 0 ; J <=和[N]; J ++ ){ 53の ANS = 分(ANS、DP [n]は[J])。 54 } 55 のprintf(" %Dを\ n " 、ANS)。 56 リターン 0 。 57 }