二次元平面上に酒屋と配達先が $N$ 個あり,それぞれの座標 $(X_k,Y_k)$ が与えられる.
また,各配達先 $k$ に配達する荷物の重量 $W_k$ が与えられる.
道路は碁盤の目上になっており,ある地点から別の地点まで移動するのに必要な移動距離はマンハッタン距離となる.
トラックに荷物を合計で $w$ だけ積んでいる場合は,単位距離当たりの移動時間が $(w+100)/120$ だけ必要になる.
最初にトラックに全ての荷物を積んで,$N$ 箇所の配達先を巡って,酒屋に戻る.
各配達先では,その配達先に配達する荷物を降ろす.
重さ $w$ の荷物を降ろす際には,時間が $w$ だけかかる.
既に全ての荷物は積んである状態でトラックは酒屋にある.
全ての荷物を配達して酒屋に戻るまでの最短時間を求める問題.
#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)
#define mygc(c) (c)=getchar_unlocked()
#define mypc(c) putchar_unlocked(c)
void reader(int *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);}
void reader(double *x){scanf("%lf",x);}
template <class T, class S> void reader(T *x, S *y){reader(x);reader(y);}
template <class T, class S, class U> void reader(T *x, S *y, U *z){reader(x);reader(y);reader(z);}
void writer(double x, char c){printf("%.15f",x);mypc(c);}
template<class T> void writerLn(T x){writer(x,'\n');}
double dd(double dx, double dy){ return fabs(dx)+fabs(dy); }
int X0, Y0;
int N;
int X[20], Y[20]; double W[20];
double sum[50000];
double dist[20][20];
double dp[50000][20];
int main(){
int i, j, k, mask;
double add, res;
reader(&X0,&Y0);
reader(&N);
rep(i,N) reader(X+i,Y+i,W+i), X[i]-=X0, Y[i]-=Y0;
X[N] = Y[N] = 0;
W[N] = 0;
N++;
rep(i,1<<N){
sum[i] = 0;
rep(j,N+1) if(i&1<<j) sum[i] += W[j];
}
rep(i,N) rep(j,N){
dist[i][j] = dd(X[i]-X[j], Y[i]-Y[j]);
}
rep(i,1<<N) rep(j,N) dp[i][j] = 1e100;
dp[(1<<N)-1][N-1] = 0;
for(i=(1<<N)-1;i>=0;i--) rep(j,N) if(dp[i][j] < 1e90){
rep(k,N) if(i&1<<k){
add = dist[j][k] * (100 + sum[i]) / 120;
dp[i^(1<<k)][k] = min(dp[i^(1<<k)][k], dp[i][j] + add);
}
}
res = dp[0][N-1] + sum[(1<<N)-1];
writerLn(res);
return 0;
}
Current time: 2024年04月24日00時27分33秒
Last modified: 2015年01月29日00時14分22秒 (by laycrs)
Tags: Competitive_Programming yukicoder
トップページに戻る
Logged in as: unknown user (not login)