題解 P4046 JSOI2010 快遞服務

2022-06-20 20:24:12 字數 1220 閱讀 7949

這道題其實和sp703 service - mobile service一樣

看到這到題,很容易想到一種定義狀態的方式\(f[i][x][y][z]\)表示完成前\(i\)個請求,三個人的位置分別在\(x,y,z\),但很明顯如果這麼定義會超空間,所以想辦法減掉一位,因為完成請求必須要有乙個人在請求發生的位置,那麼,我們就可以用當前完成的第\(i\)個請求來推出其中乙個人的位置,所一這個狀態就可變成\(f[i][x][y]\),b表示完成前\(i\)個請求時,其中兩個人分別在\(x,y\),接下來考慮怎麼轉移狀態,如果我們從前面的狀態來推當前的狀態,需要考慮許多種情況,所以我們就用當前狀態來更新下乙個狀態

然後是狀態轉移方程,因為有三個員工,那麼我們可以考慮,下面三種情況

在當前請求的位置的人去

\(f[i + 1][x][y] = min(f[i + 1][x][y], f[i][x][y] + c[p[i]][p[i+1]])\)

在\(x\)位置的員工去

\(f[i + 1][p[i]][y] = min(f[i + 1][p[i]][y], f[i][x][y]+c[x][p[i + 1]])\)

在\(y\)位置的員工去

\(f[i + 1][x][p[i]] = min(f[i + 1][x][p[i]], f[i][x][y]+c[y][p[i + 1]])\)

得出狀態轉移方程,這到題就基本解決了,但如果你直接這麼定義,對於這到題會超空間,所以考慮滾動陣列優化,對於每乙個狀態,它只和它的前乙個狀態有關,所以我們可以把陣列的第一位壓縮為兩維

附**

#include#include#includeusing namespace std;

int f[2][205][205];

int c[205][205], p[1005];

int main()

}int n = 0;

while(scanf("%d", &p[++n])!=eof);

memset(f, 0x3f, sizeof(f));

f[0][1][2] = 0;

p[0] = 3;

for (int i = 0; i < n;i++)}}

int ans = 0x3f3f3f3f;

for (int i = 1; i <= l;i++)

for (int j = 1; j <= l;j++)

printf("%d", ans);

}

P4046 JSOI2010 快遞服務

傳送門 很容易想出 o n 3m 的方程,三維分別表示某個快遞員現在在 然後直接遞推即可 然而這樣會t,考慮怎麼優化。我們發現每一天的時候都有乙個快遞員的位置是確定的,即在前一天要到的位置。那麼我們只要列舉剩下的兩個人分別在 就行了,複雜度變為 o n 2m minamoto include def...

P4046 JSOI2010 快遞服務

題目鏈結 雙倍經驗 有 m 個位置,從位置 p 移動到位置 q 需要花費 c p,q 的價錢,但並不保證 c p,q c q,p 現在有三個員工,初始位置在 1,2,3 和有 n 個請求,任何時刻只有一名員工可以移動,且不允許同一位置上有 2 個以上員工。第 i 個請求發生在位置 p i 公司必須按...

P4047 JSOI2010 部落劃分題解

題意 給定一些點,要把這些點分為k個部落,問最近兩個部落間的最遠距離是多少。解法 二分答案 並查集檢測鴨!二分的時候要注意精度問題噢,eps開到1e 3會有乙個點過不去。開始看錯題意想半天。include include include include include include include...