日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【UVA - 10037】Bridge(过河问题,经典贪心)

發布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【UVA - 10037】Bridge(过河问题,经典贪心) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題干:

題目大意:

有N個人要過橋,每個人速度不同,只有一個手電筒,每次最多只能過去兩個人,問所有人最短的過橋時間為多少

解題報告:

? 首先讓最快的兩個人最后過,然后我們分奇偶考慮,分別處理到剩下三個人和兩個人的情況。然后在做最后的處理。

? 除了最后的處理(其實是最先執行的步驟),我們看其他的步驟,現在最快的倆人都在對岸。

? ?現在兩種貪心策略:(一個回合就處理兩個人,每個回合把當前速度最慢的兩個人帶到河岸)

? ? ? 1.最快速度的人每次帶一個當前速度最慢的人過去,自己返回;再帶一個當前速度最慢的人過去, 再返回(也就是這倆最慢的都讓最快的帶回來)

??????2.最快速度的人和速度第二快的人一起過去;最快速的人返回,速度最慢的兩個人一起過去;速度第二快的人返回。

? ? 對于每一個回合,我們去這兩種策略中的較小值,,貪心即可得到答案。

?????????

AC代碼:

//該死的格式錯誤怎么不提示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];//先跑過去 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 ;}

? 就像學長說的,這題重要的是這個貪心的思路,可以構造出很多不同的題型:比如學長講課時說的,可以和置換群建立起關系。比如構造一個題:

? ? ?給你n個數(數值保證從1~n 且互不相同),先定義一種操作:可以任選兩個元素進行交換,交換的代價是這兩個元素值的和。現在問你如果我要吧這個序列變成一個有序序列,最小的代價是多少。

? ?首先我們知道,我們要找一些輪換,然后這一些輪換對調就可以了,根據置換群的知識,我們知道可以把這些對調換成一個個的對換去完成,并且如果這一個輪換涉及k個元素的話,我們需要對換k-1次,那么既然次數確定,并且需要有一個作為每次都出現的(詳情見離散數學),那我們就貪心那個最小的作為每一次對換都出現的元素,,這一點并不難想。。但是有沒有可能有更優的選擇?比如我們(100,102,104,103,105,106,107,108)這有八個元素組成一個輪換的話(順序是我瞎寫的)那我們肯定選100當那個每次都出現在對換中的元素,,但是我們想,有沒有可能把另外一個最小的元素換過來當成最小的元素,換完了以后再換回去呢?比如還有一個輪換(1,2,3),那么我們先1和100對調,然后再用1去做那7次對換,然后再把1和100調回去,這樣代價肯定小了很多啊、、這里僅提供思路,,具體題目遇到再說、

?

總結

以上是生活随笔為你收集整理的【UVA - 10037】Bridge(过河问题,经典贪心)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。