【UVA - 10037】Bridge(过河问题,经典贪心)
題干:
題目大意:
有N個(gè)人要過(guò)橋,每個(gè)人速度不同,只有一個(gè)手電筒,每次最多只能過(guò)去兩個(gè)人,問(wèn)所有人最短的過(guò)橋時(shí)間為多少
解題報(bào)告:
? 首先讓最快的兩個(gè)人最后過(guò),然后我們分奇偶考慮,分別處理到剩下三個(gè)人和兩個(gè)人的情況。然后在做最后的處理。
? 除了最后的處理(其實(shí)是最先執(zhí)行的步驟),我們看其他的步驟,現(xiàn)在最快的倆人都在對(duì)岸。
? ?現(xiàn)在兩種貪心策略:(一個(gè)回合就處理兩個(gè)人,每個(gè)回合把當(dāng)前速度最慢的兩個(gè)人帶到河岸)
? ? ? 1.最快速度的人每次帶一個(gè)當(dāng)前速度最慢的人過(guò)去,自己返回;再帶一個(gè)當(dāng)前速度最慢的人過(guò)去, 再返回(也就是這倆最慢的都讓最快的帶回來(lái))
??????2.最快速度的人和速度第二快的人一起過(guò)去;最快速的人返回,速度最慢的兩個(gè)人一起過(guò)去;速度第二快的人返回。
? ? 對(duì)于每一個(gè)回合,我們?nèi)ミ@兩種策略中的較小值,,貪心即可得到答案。
?????????
AC代碼:
//該死的格式錯(cuò)誤怎么不提示PE了??怎么成WA了???? #include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 2e5 + 5; int a[MAX]; int main() {int t,n;cin>>t;while(t--) {int ans = 0;scanf("%d",&n);for(int i = 1; i<=n; i++) scanf("%d",a+i);sort(a+1,a+n+1);if(n == 1) {printf("%d\n%d\n",a[1],a[1]);if(t) puts("");continue;}if(n == 2) {printf("%d\n%d %d\n",a[2],a[1],a[2]);if(t) puts("");continue;}int res,time=0;if(n%2==1) res=3;else res=2;for(int i = n; i>res; i-=2) {ans += a[1]+a[i];//先跑過(guò)去 if(a[2]*2<a[i-1]+a[1]) ans += a[2] + a[2];else ans += a[i-1]+a[1];}if(n%2 == 1) ans += a[1]+a[2]+a[3];else ans += a[2];printf("%d\n",ans);if(n == 3) {printf("%d %d\n%d\n",a[1],a[2],a[1]);printf("%d %d\n",a[1],a[3]);if(t) puts("");continue;}for(int i = n; i>res; i-=2) {if(a[2]*2 < a[i-1]+a[1]) {printf("%d %d\n%d\n", a[1], a[2], a[1]);printf("%d %d\n%d\n", a[i-1], a[i], a[2]);}else {printf("%d %d\n%d\n", a[1], a[i-1], a[1]);printf("%d %d\n%d\n", a[1], a[i], a[1]);}}if(n%2==1) {printf("%d %d\n%d\n", a[1], a[2], a[1]);printf("%d %d\n", a[1], a[3]);}else printf("%d %d\n",a[1],a[2]);if(t) puts("");} return 0 ;}? 就像學(xué)長(zhǎng)說(shuō)的,這題重要的是這個(gè)貪心的思路,可以構(gòu)造出很多不同的題型:比如學(xué)長(zhǎng)講課時(shí)說(shuō)的,可以和置換群建立起關(guān)系。比如構(gòu)造一個(gè)題:
? ? ?給你n個(gè)數(shù)(數(shù)值保證從1~n 且互不相同),先定義一種操作:可以任選兩個(gè)元素進(jìn)行交換,交換的代價(jià)是這兩個(gè)元素值的和。現(xiàn)在問(wèn)你如果我要吧這個(gè)序列變成一個(gè)有序序列,最小的代價(jià)是多少。
? ?首先我們知道,我們要找一些輪換,然后這一些輪換對(duì)調(diào)就可以了,根據(jù)置換群的知識(shí),我們知道可以把這些對(duì)調(diào)換成一個(gè)個(gè)的對(duì)換去完成,并且如果這一個(gè)輪換涉及k個(gè)元素的話,我們需要對(duì)換k-1次,那么既然次數(shù)確定,并且需要有一個(gè)作為每次都出現(xiàn)的(詳情見(jiàn)離散數(shù)學(xué)),那我們就貪心那個(gè)最小的作為每一次對(duì)換都出現(xiàn)的元素,,這一點(diǎn)并不難想。。但是有沒(méi)有可能有更優(yōu)的選擇?比如我們(100,102,104,103,105,106,107,108)這有八個(gè)元素組成一個(gè)輪換的話(順序是我瞎寫(xiě)的)那我們肯定選100當(dāng)那個(gè)每次都出現(xiàn)在對(duì)換中的元素,,但是我們想,有沒(méi)有可能把另外一個(gè)最小的元素?fù)Q過(guò)來(lái)當(dāng)成最小的元素,換完了以后再換回去呢?比如還有一個(gè)輪換(1,2,3),那么我們先1和100對(duì)調(diào),然后再用1去做那7次對(duì)換,然后再把1和100調(diào)回去,這樣代價(jià)肯定小了很多啊、、這里僅提供思路,,具體題目遇到再說(shuō)、
?
總結(jié)
以上是生活随笔為你收集整理的【UVA - 10037】Bridge(过河问题,经典贪心)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: A股高管薪酬第二高 为1500万年薪加入
- 下一篇: 【CodeForces - 507B】A