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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

贪心专题技巧

發布時間:2025/3/19 编程问答 9 豆豆
生活随笔 收集整理的這篇文章主要介紹了 贪心专题技巧 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

貪心專題

  • 制定參賽順序
  • 調度問題
    • 加熱便當
  • 米那斯雅諾

制定參賽順序

貪心策略:
如果己方最低的也比我方最高的高,就讓我方最低的去,否則在能獲勝的情況下選取我方分數大于其第一個去。

小技巧:可以利用二叉搜索樹(mutiset)在保存我方的,因為在保存的時候,會默認由低到高排序,

代碼:

int order(const vector<int>&russion,const vector<int>&korean){int n = russion.size(),wins = 0;multiset<int>ratings(korean.begin(),korean.end());for(int rus = 0;rus<n;++rus){if(*ratings.rbegin()<russion[rus])ratings.erase(ratings.begin());else{ratings.erase(ratings.lower_bound(russion[rus]));++wins;}}return wins; }

調度問題

加熱便當

等到快中午的時候元碩才發現,營地里只有1臺可供加熱的微波爐。更糟糕的是,這臺微波爐功率太小,每次只能加熱1個便當。假設,加熱第i個便當需要耗費mi秒,吃這個便當將耗費ei秒的時間。
求最小的吃午飯時間

貪心策略

無論以何種方式最后的時間總是,所以的便當加熱時間加上其中一個吃便當的時間,這是因為最后加熱的便當只能最后被吃掉,即使之前有一個吃的時間很長,那么就是加這個之前的。
因為我們以 吃便當的時間進行降序排列。遍歷一篇即可。

代碼:

int e[N],m[N]; int heat(){//決定加熱順序vector<pair<int,int>>order;for(int i=0;i<n;++i)order.push_back(make_pair(-e[i],i)); // 負數,那么大的序號就會自動雜前邊sort(order.begin(),order.end());//模擬整個過程int ret = 0,beginEat = 0;for(int i=0;i<n;++i){int box = order[i].second; //得到序號beginEat += m[box];ret = max(ret,beginEat+e[box]);} }

米那斯雅諾

題意:
米那斯雅諾城從來沒有被攻陷過的,這里有一個半徑為8公里的巨大的圓形城墻——拉馬斯安澈。圍繞整個城市的巨大城墻中設有n個哨所,各哨所的監視范圍為以哨所為中心、半徑為r:的圓。不過,因城墻結構限制,各個哨所的設立點并不規則,而且能夠監視的范圍也各不相同。
圖中,租實線表示城墻,五星表示哨所,虛線則表示哨所的監視范圍。為了以最少兵力監視整個城墻,僅想在一部分哨所上安排哨兵。給出各個哨所的位置和監視范圍時,設計一個程序計算監視整個城墻所需的最少兵力。
為了簡便起見,假設城墻是厚度為0的圓形,而哨所是一個點。

先通過轉換,將問題轉換為圓心角區間的問題,要監視所以的圓形部分,就要判斷出監視領域的并集能否完全覆蓋[0,2pi)

const double pi = 2.0 * acos(0); int n; double y[100],x[100],r[100]; pair<double,double>ranges[100];void convertToRange(){for(int i =0;i<n;++i){double loc = fmod(2*pi + atan2(y[i],x[i]),2*pi);double range = 2.0 * asin(r[i]/2.0/8.0);ranges[i] = make_pair(loc - range,loc + range);}//默認會以起始位置最小的區間開始排序sort(ranges,ranges); }

fmod()函數:
頭文件:#include< cmath >
fmod()用來對浮點數進行取模(求余)。設x=k*n+h,則返回值為h(h和x的符號相同)。

貪心求解

const int INF = 987654321; int n; pair<double,double>ranges[100]; // 選擇覆蓋0點的區間后,剩余的展成線段int solveCircular(){int ret =INF;//按起始位置升序排列各區間sort(ranges,ranges+n);//選擇覆蓋0點的區間后for(int i=0;i<n;++i)if(ranges[i].first<=0||ranges[i].second>=2*pi){// 排除被此區間覆蓋的部分后,剩余的圓心角區間double begin = fmod(ranges[i].second,2*pi);double end = fmod(ranges[i].first+2*pi,2*pi);ret = min(ret,1+solveLinear(begin,end))} }int solveLinear(double begin,double end){int used = 0,idx = 0;//只要有未覆蓋的線段就一直執行while(begin<end){//在begin 之前的起始區間中求出離右端點最近的區間double maxCover = -1;while(idx < n&& ranges[idx].first <= begin){maxCover = max(maxCover,ranges[idx].second);++idx;}//未找到能夠覆蓋的區間時if(maxCover <= begin)return INF;//去掉已被覆蓋的線段begin = maxCover;++ used;}return used; }

總結

以上是生活随笔為你收集整理的贪心专题技巧的全部內容,希望文章能夠幫你解決所遇到的問題。

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