【洛谷 - P1772 】[ZJOI2006]物流运输(dp)
題干:
題目描述
物流公司要把一批貨物從碼頭A運(yùn)到碼頭B。由于貨物量比較大,需要n天才能運(yùn)完。貨物運(yùn)輸過程中一般要轉(zhuǎn)停好幾個(gè)碼頭。物流公司通常會設(shè)計(jì)一條固定的運(yùn)輸路線,以便對整個(gè)運(yùn)輸過程實(shí)施嚴(yán)格的管理和跟蹤。由于各種因素的存在,有的時(shí)候某個(gè)碼頭會無法裝卸貨物。這時(shí)候就必須修改運(yùn)輸路線,讓貨物能夠按時(shí)到達(dá)目的地。但是修改路線是—件十分麻煩的事情,會帶來額外的成本。因此物流公司希望能夠訂一個(gè)n天的運(yùn)輸計(jì)劃,使得總成本盡可能地小。
輸入輸出格式
輸入格式:
?
第一行是四個(gè)整數(shù)n(l≤n≤100)、m(l≤m≤20)、K和e。n表示貨物運(yùn)輸所需天數(shù),m表示碼頭總數(shù),K表示每次修改運(yùn)輸路線所需成本,e表示航線條數(shù)。接下來e行每行是一條航線描述,包括了三個(gè)整數(shù),依次表示航線連接的兩個(gè)碼頭編號以及航線長度(>0)。其中碼頭A編號為1,碼頭B編號為m。單位長度的運(yùn)輸費(fèi)用為1。航線是雙向的。再接下來一行是一個(gè)整數(shù)d,后面的d行每行是三個(gè)整數(shù)P(1<P<m),a,b(1≤a≤b≤n)。表示編號為P的碼頭從第a天到第b天無法裝卸貨物(含頭尾)。同一個(gè)碼頭有可能在多個(gè)時(shí)間段內(nèi)不可用。但任何時(shí)間都存在至少一條從碼頭A到碼頭B的運(yùn)輸路線。
?
輸出格式:
?
包括了一個(gè)整數(shù)表示最小的總成本。總成本=n天運(yùn)輸路線長度之和+K*改變運(yùn)輸路線的次數(shù)。
?
輸入輸出樣例
輸入樣例#1:?復(fù)制
5 5 10 81 2 11 3 31 4 22 3 22 4 43 4 13 5 24 5 242 2 33 1 13 3 34 4 5輸出樣例#1:?復(fù)制
32說明
【樣例輸入說明】
上圖依次表示第1至第5天的情況,陰影表示不可用的碼頭。
【樣例輸出說明】
前三天走1-4-5,后兩天走1-3-5,這樣總成本為(2+2)*3+(3+2)*2+10=32。
_NOI導(dǎo)刊2010提高(01)
解題報(bào)告:
? ? 這題第一眼看的時(shí)候是沒思路的。。。聽學(xué)長講完woc好簡單。想到狀壓了但是不知道怎么用。
? 這題做法很多,其中一種就是先算出2^18中每一種狀態(tài)下,1到m的最短路是多少復(fù)雜度mlogm * 2^18,空間復(fù)雜度d[2^18],應(yīng)該不會爆。
? ?然后這題注意到不光點(diǎn)數(shù)很少,天數(shù)也很少,所以你可以預(yù)處理任意兩天之間,如果不更換線路的話,路徑最小值。也就是假設(shè)你要算i~j天的,所以首先要枚舉每一天然后處理出一個(gè)可行狀態(tài)來,然后直接與運(yùn)算就可以得到可行狀態(tài)了,然后再你預(yù)處理的d數(shù)組中取數(shù)就可以了,這就是當(dāng)前最優(yōu)值。然后xjb做就可以了。
? 這題還有另一種十分好想并且不會卡空間的做法。詳情見代碼。
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int INF = 0x3f3f3f3f; const int MAX = 2e5 + 5; struct Edge {int to,ne;ll w; } ee[MAX]; int n,m,k,e,D; ll dis[22],d[222][222]; int ban[22][222]; struct Point {int pos;ll c;Point(int pos,ll c):pos(pos),c(c){}bool operator < (const Point & b) const{return c > b.c;} }; int head[22],tot,vis[22]; void add(int u,int v,ll w) {ee[++tot].to = v;ee[tot].w = w;ee[tot].ne = head[u];head[u] = tot; } ll Dijkstra() {for(int i = 1; i<=m; i++) dis[i] = INF;priority_queue<Point> pq;pq.push(Point(1,0)); dis[1] = 0;while(pq.size()) {Point cur = pq.top();pq.pop();if(vis[cur.pos]) continue;vis[cur.pos] = 1;for(int i = head[cur.pos]; ~i; i = ee[i].ne) {int v = ee[i].to;if(vis[v]) continue;if(dis[v] > dis[cur.pos] + ee[i].w) {dis[v] = dis[cur.pos] + ee[i].w;pq.push(Point(v,dis[v]));}}}return dis[m]; } ll dp[222]; int main() {cin>>n>>m>>k>>e;for(int i = 1; i<=m; i++) head[i] = -1;for(int a,b,c,i = 1; i<=e; i++) {scanf("%d%d%d",&a,&b,&c);add(a,b,c);add(b,a,c);}cin>>D;for(int a,b,c,i = 1; i<=D; i++) {scanf("%d%d%d",&a,&b,&c);for(int j = b; j<=c; j++) ban[a][j] = 1;}for(int i = 1; i<=n; i++) {//枚舉每一區(qū)間段的起點(diǎn) for(int j = i; j<=n; j++) {//枚舉終點(diǎn) for(int tar = 1; tar<=m; tar++) {vis[tar]=0;for(int k = i; k<=j; k++) vis[tar] |= ban[tar][k];}d[i][j] = Dijkstra();//預(yù)處理出第i到第j天的最短路 } }memset(dp,INF,sizeof dp);dp[1] = d[1][1];for(int i = 2; i<=n; i++) {dp[i] = d[1][i]*i;for(int j = 2; j<=i; j++) {if(d[j][i]==INF) continue;dp[i] = min(dp[i],dp[j-1] + d[j][i]*(i-j+1) + k);}}printf("%lld\n",dp[n]);return 0 ; }?
總結(jié)
以上是生活随笔為你收集整理的【洛谷 - P1772 】[ZJOI2006]物流运输(dp)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 平安银行信用卡审核要多久出结果 申请方式
- 下一篇: 【 HDU - 3062】Party(2