演算法模板:貪心
阿新 • • 發佈:2020-09-21
-
貪心:
-
原理:區域性選擇最優解,當前選擇對後續不產生影響
-
基本思路:
① 建立數學模型來描述問題
② 分解為若干子問題
③ 依序對每一個子問題求最優解(下一個包含上一個的最優解)
④ 把所有子問題的區域性最優解合併為原問題的一個解
-
活動安排問題
-
會場安排活動:即按活動的結束時間排序,讓剩餘時間最大化,安排更多的活動
-
程式碼:
bool cmp1(node a, node b) { return a.end < b.end ; //結束時間從小到大排序 } sort(Num+1, Num+n+1, cmp1); for(int i=2; i<=n; i++) { if(Num[i].begin >= Num[1].end) { Num[1].end = Num[i].end ; //更新結束時間 count++; } }
-
活動安排會場:按活動的開始時間排序,如果時間衝突則加一個會場
-
程式碼:
bool cmp(node a,node b) { return a.start < b.start; } sort(Num,Num+n,cmp); b[0]=p[0].end ; sum = 1; for(i=1; i<n; i++) { for(j=0; j<sum; j++) { if(b[j] <= p[i].start )//找到房間,更新結束時間 { b[j]=p[i].end ; break; } } if(j==sum)//未找到房間,更新結束時間 { b[sum]=p[i].end ; ++sum; } }
-
-
找零錢問題:
-
問題描述:找錢,有幾種不同面值的貨幣,求最少使用多少張
-
策略:優先使用面值大的貨幣
-
程式碼:
int num = 4; //4種 int m[] = {25,10,5,1}; //面值 int target = 99; //要找 int count[4]; //記錄每種面值需多少 for(int i=0; i<num; i++) { count[i] = target / m[i]; target = target % m[i]; }
-
-
揹包問題:
- 問題描述:一堆物品,在負重允許下取最高價值
- 策略:
- 優先選擇價值最大者(value)
- 優先選擇重量最小者(weight)
- 優先選擇價效比最高者(value / weight)
- 以上三者無具體情況無法確定究竟是哪種策略最優
-
均分紙牌:
-
問題描述:N堆紙牌,從任一堆上去任意張到臨邊牌堆,最少多少次使牌堆一樣多
-
策略:每次都考慮從i牌堆取來a[i]-avg張牌使a[i+1]達到均值
-
程式碼:
for(int i=0; i<n-1; i++) { if(a[i] != avg ) { int move = a[i] - avg; a[i] -= move; a[i+1] += move; times ++; } }
-
-