この道DPの問題は、私は2時間はいつも彼らは私は考え状態、最終的な敗北を持っていない状態空間の状態のセット全体を負担していないと感じて考えて、より困難として記述することができます。
正解は、我々は確かに次元を持っていることを私は私にこの男のディナーを表しているが、私は後ろの7人を食べる前に、あなたは一次元jを追加する必要がそう言った、食べてそうな彼と7人の症状の背後に、食事の費用及びkは食べるために最後の人を表して関係者、まだのビットを転送されていない、この次元のkは、当社の状態次元表現の状態を変更するにはあまりにも多くの不必要な試みを包含しているので私は離れて人々の最後の食事からでした。明らかに[-8、7]。
この状態について慎重に考えて、それは状態をシフトし始めることができ、状態空間のすべてが含まれています。
// の#include <ビット/ STDC ++。H> の#include <iomanip> の#include <iostreamの> する#include <cstdioを> する#include <CStringの> する#include < ストリング > の#include <キュー> の#include <両端キュー> する#include <cmath > の#include <CTIME> の#include <cstdlib> の#include <スタック> の#include <アルゴリズム> の#include <ベクトル> の#include <CCTYPE> の#include <ユーティリティ> の#include < 設定 > 書式#include <ビットセット> の#include<地図> の#define INF 1000000000 の#defineっ長い長 の#define分(X、Y)((X)>(Y)?(Y):( X)) の#define MAX(x、y)は((X)> (Y)(X):( Y))? の#define RI登録LL の#define DB二重 の#define EPS 1E-8を 使用して 名前空間STD。 チャー BUF [ 1 << 15 ]、* FS、* FT。 インラインチャーGETC() { リターン(FS ==フィート&&(FT =(FS = BUF)+関数fread(BUF、1、1 << 15、STDIN)、FS ==フィート))?0:* FS ++ ; } インラインint型リード() { int型のx = 0、F = 1。チャー CH = GETC()。 一方、(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - ')、F = - 1 ; CH = GETC();} 一方(CH> = ' 0 ' && CH <= ' 9 '){X = X * 10 + CH- ' 0 ' ; CH = GETC();} 戻りのx *のF。 } //SDOI DP(A | B)を考慮最小キュー時間のための- (A&B) // F明確に状態は[I] [J] [ k]の人に示しiと自分自身とバック7状態jを食べるかどうかK.のときiが最小コストである距離を食べる人 のconst int型 MAXN = 1010 ; INT N-、T、マックスは、 int型;、B [MAXN] [MAXN]を INT [F [MAXN] 。1 << 。8 ] [ 20である]; int型のmain() { // freopenは( "1.In"、 "R&LT"、STDIN); T = 読む(); 一方(T-- ) { N- = 読む(); のmemset(F、10、sizeof ] [(F))。 MAXX = F [ 00 ] [ 0 ]。 用(int型 iは= 1 ; iが<= N; I ++)[i]を読み出す=()、[I] = B )(読み取ります。 F [ 1 ] [ 0 ] [ 7 ] = 0。// K的值域[-8,7]整体平移8 ための(int型 i = 1 ; iが<= N; ++ I) { ため(INT J = 0 ; J <(1 << 8); ++ J) { ための(int型のk = 0 ; K <= 15 ; ++ K) { IF(F [I] [J] [K] ==マックス)が続行; IF(J&1 [Iが+)F 1 ] [J >> 1。 [ - K-] 1。 ] =分(F [Iは、+ 1。 ] [J >> 1 ] - [K- 1 ]、F [I] [J] [K]); 他 { int型の限界= マックス; のための(int型 L = 0 ; L <= 7 ; L ++)// 列挙コンタクト食べる人ダウン { IF(J&(1 << L))続け; あれば(私はL>リミット+)ブレーク。 限界 =分(限界、私は[iが+ L + Bを+ L])を、 F [I] [J |(1 << L)]、[L + 8 ] =分(F [I] [J |(1 << L)]、[L + 8 ]、F [i]は[J] [K] +((私はK- + 8?)([I + K- 8)] ^ [iが+ L]を:0 )); // COUT << F [I] [J |(1 << L)]、[L + 8] << ENDL。 } } } } } int型 ANS =MAXX; 以下のために(int型 i = 0 ; iが<= 8 ; ++ I)ANS =分(ANS、F [N + 1 ] [ 0 ] [I])。 printf(" %d個の\ n " 、ANS)。 } 戻り 0 。 }
Sahua〜