2016级算法期末模拟练习赛-A.wuli51和京导的毕业旅行
生活随笔
收集整理的這篇文章主要介紹了
2016级算法期末模拟练习赛-A.wuli51和京导的毕业旅行
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1063 wuli51和京導的畢業旅行
思路
中等題,二分+貪心。
簡化題意,將m+1個數字分成n份,ans為這n段中每段數字和的最大值,求ans最小值及其方案。
對于這種求最小的最大值,最常用的方法是二分。答案一定在[0,sum]之間,通過判斷是否符合要求可以求得ans。在本題中,ans一定是整數,所以二分過程中left、mid、right也是整數。
如何判斷是否符合要求?對于某一mid值,遍歷一次露營地距離數組,通過貪心,總是使一天內的行程盡可能接近mid,但不可超過mid。若是加上某一露營地距離超過了mid,代表需要露營一次。最后通過比較露營數cnt與數據要求n-1的大小判斷是否符合要求。
那又如何輸出方案呢?其實在二分的過程中已經體現了,恰好題目中也是要求前面行程數x盡可能大。所以貪心輸出,總是盡可能填滿某一天的行程。
貪心還需要注意一個問題,就是輸出必須得有n個數,也就是說貪心前得判斷一下后面是否有足夠的數保準每天都有行程。例如對于n=3,m=2,xi=3,2,1,輸出ans應為3,方案應為3,2,1,而不是3,3。
分析
時間復雜度:O(nlgn)。
參考代碼
// // Created by AlvinZH on 2017/12/6. // Copyright (c) AlvinZH. All rights reserved. //#include <cstdio>int n, m; int sum;//行程總和 int D[10005];bool check(int X) {int cnt = 0;int temp = 0;for(int i = 1; i <= m; i++){if(D[i] > X) return false;if(temp + D[i] > X){temp = D[i];cnt++;}elsetemp += D[i];}return cnt <= n-1; }int MinMaxX()//二分法求得min(max(xi)) {int l = 0, r = sum;while(l <= r){int mid = (l+r) / 2;if(check(mid))r = mid - 1;elsel = mid + 1;}return l; }int main() {while(~scanf("%d %d", &n, &m)){sum = 0;m += 1;for(int i = 1; i <= m; i++){scanf("%d", &D[i]);sum += D[i];}int ans = MinMaxX();printf("%d\n", ans);int cnt = 0;int temp = 0;for(int i = 1; i <= m; i++){if(D[i]+temp > ans || n-1 - cnt > m-i)//無法合并||只剩下m-i段,[i+1~m]{printf("%d ", temp);temp = D[i];cnt++;}elsetemp += D[i];}printf("%d\n", temp);} }轉載于:https://www.cnblogs.com/AlvinZH/p/8137702.html
總結
以上是生活随笔為你收集整理的2016级算法期末模拟练习赛-A.wuli51和京导的毕业旅行的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sharepoint 场帐号修改密码
- 下一篇: C/C++获取系统当前时间