題目鏈結
雙倍經驗
有\(m\)個位置,從位置\(p\)移動到位置\(q\)需要花費\(c(p,q)\)的價錢,但並不保證\(c(p,q)≠c(q,p)\)
現在有三個員工,初始位置在\(1,2,3\)和有\(n\)個請求,任何時刻只有一名員工可以移動,且不允許同一位置上有 \(2\) 個以上員工。第 \(i\) 個請求發生在位置 \(p_i\),公司必須按照順序,派一名員工到位置 \(p_i\)去完成請求
求公司的最小花費。
設\(f(i,x,y,z)\)表示解決完前\(i\)個請求時,三個員工分別在\(x,y,z\)處時的最小花費,轉移:
\(f(i+1,p_,y,z) = min\)\}\qquad (p_≠y≠z)\)
\(f(i+1,x,p_,z) = min\)\}\qquad (x≠p_≠z)\)
\(f(i+1,x,y,p_) = min\)\}\qquad (x≠y≠p_)\)
時空複雜度\(o(nm^3)\),無論是在時間上還是空間上都接受不了
考慮優化:
可以發現,在完成第\(i\)個任務時,一定有乙個人站在\(p_i\)的位置上,也就是說,這個人的資訊是"多餘"的,只需要記錄另外兩個人的位置
設\(f(i,x,y)\)表示解決前\(i\)個請求時,三個員工分別在\(x,y,p_i\)時的最小花費,轉移:
\(f(i+1,p_i,y) = min\)\}\qquad (p_i≠y≠p_)\)
\(f(i+1,x,y) = min\)\}\qquad (x≠y≠p_)\)
\(f(i+1,x,p_i) = min\)\}\qquad (x≠p_i≠p_)\)
時間複雜度\(o(nm^2)\),再用滾動陣列優化一下空間即可
/*
xcxc82
*/#includeusing namespace std;
#define inf 1e9+10
const int maxn = 210;
int t,l,n;
inline int read()
while(ch>='0'&&ch<='9')
if(flag) return x;return ~(x-1);
}int f[2][maxn][maxn];
int val[maxn][maxn],a[maxn*5];
int main()
} a[0] = 3;
f[0][1][2] = 0;
int now;
while(cin>>now) a[++n] = now;
for(int i=0;i<=n-1;i++)
}} int ans = 0x3f3f3f3f;
for(int i=1;i<=l;i++)
for(int j=1;j<=l;j++)
ans = min(ans,f[n&1][i][j]);
printf("%d",ans);
return 0;
}
P4046 JSOI2010 快遞服務
傳送門 很容易想出 o n 3m 的方程,三維分別表示某個快遞員現在在 然後直接遞推即可 然而這樣會t,考慮怎麼優化。我們發現每一天的時候都有乙個快遞員的位置是確定的,即在前一天要到的位置。那麼我們只要列舉剩下的兩個人分別在 就行了,複雜度變為 o n 2m minamoto include def...
題解 P4046 JSOI2010 快遞服務
這道題其實和sp703 service mobile service一樣 看到這到題,很容易想到一種定義狀態的方式 f i x y z 表示完成前 i 個請求,三個人的位置分別在 x,y,z 但很明顯如果這麼定義會超空間,所以想辦法減掉一位,因為完成請求必須要有乙個人在請求發生的位置,那麼,我們就可...
P4171 JSOI2010 滿漢全席
傳送門 顯然的 2 sat 問題,甚至不用輸出方案 每種菜不是漢式就是滿式,分成兩個節點 i,n i 分別表示滿式和漢式 對於限制 m i,m j 如果 i 為漢式則 j 一定要為滿式,如果 j 為漢式 i 一定為滿式 所以連邊 n i,j n j,i 其他情況同理,最後 tarjan 縮一下聯通塊...