生活随笔
收集整理的這篇文章主要介紹了
【2018NOIP普及组】T3 摆渡车
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
P5017 擺渡車
題目傳送門
思路:
對于每一個人他的最長等待時間為m-1。車剛走,他下分鐘到。f[i][j]表示第i個人等j分鐘的所有人的最小等待時間(最優(yōu)解)。注意:第i個人等0分鐘(他來就開車),不一定是最優(yōu)的。深搜第i人在開車時間為st時得最優(yōu)解,把它的值賦給f[i][st-a[i]]; (記憶化)第i個人在開車時間為st時,這班車上(車)的人總等待時間=st*(j-i)-sum;sum為上車的人到達(dá)時間和。然后再加上第j個人,開車時間為(st+m)的最優(yōu)值(dfs(j,st+m),我們就初步得到一個最優(yōu)解(不一定是最優(yōu)的)接下來對于best,我們還需更新最優(yōu)值;(如果 第i個人后還有人沒上車,那么以st為開車時間不一定是最優(yōu)的)這里我給出一種情況,大家就比較好理解了。只有2個人,第一個1分鐘時到,第二個人2分鐘到,m=10,st=1并不是最優(yōu)的。
要想不超時,記憶化+剪枝是法寶!
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std
;
const int MAX
=2147483647;
const int N
=5e2+5;
int a
[N
],f
[N
][N
],n
,m
;
void input()
{scanf("%d%d",&n
,&m
);for(int i
=1;i
<=n
;i
++) scanf("%d",&a
[i
]);sort(a
+1,a
+1+n
);
}
int dfs(int i
,int st
)
{ if(i
>n
) return 0; if(st
<a
[i
]) return dfs(i
,a
[i
]);if(f
[i
][st
-a
[i
]]) return f
[i
][st
-a
[i
]];int sum
=0,j
=i
; while(j
<=n
&&a
[j
]<=st
) sum
+=a
[j
++];int best
=st
*(j
-i
)-sum
+dfs(j
,st
+m
);for(;j
<=n
;j
++){sum
+=a
[j
];best
=min(a
[j
]*(j
-i
+1)-sum
+dfs(j
+1,a
[j
]+m
),best
);}return f
[i
][st
-a
[i
]]=best
;
}
int main()
{input();cout
<<dfs(1,a
[1]);return 0;
}
總結(jié)
以上是生活随笔為你收集整理的【2018NOIP普及组】T3 摆渡车的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。