貪心的基本知識就不說了...比較基礎的
貪心算法的基本步驟:
1、從問題的某個初始解出發。
2、採用循環語句,當可以向求解目標前進一步時,就根據局部最優策略,得到一個部分解,縮小問題的範圍或者規模。
貪心算法應用於:
1、引導問題。最基本的就是HDU 1009 FatMouse' Trade(水題小能手hhhhh)。
2、時間序列問題。(覺得其實就是活動安排問題。)
具體解釋下:
已知N個事件的發生時刻和結束時刻(事件已經按照結束時刻升序排序)。一些在時間上沒有重疊的事件,可以構成一個事件序列。
事件序列包含的時間數目,稱爲該事件序列的長度。
試找出一個最長的事件序列。
分析:
不妨用Begin[I]和End[I]表示事件I的開始時刻和結束時刻,則原題的要求就是找一個最長的序列a1 < a2 < ...... < an,滿足:
Begin[a1] < End[a1] <= ...... <= Begin[an] < End[an].
可以證明,如果在可能的事件a1 < a2 < a3 < ...... < an中選取時間上不重疊的最長序列,那麼一定存在一個包含a1(結束最早)的最長序列。
根據這種題,書上給出的樣題是:HDU 2037 今年暑假不AC
呃......其實某破航也給出了一道題:忙碌的Nova君
<兩道題的解法幾乎相同......>
給出某官方的代碼【注意對上一個時間的記錄和處理。】(逃
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct inp
{
int x,y;
}node[105];
bool cmp(inp a, inp b)
{
return a.y < b.y;
}
int main(){
int i,j,s,n;
while(scanf("%d", &n) && n)
{
for(i = 0; i < n; i++)
cin >> node[i].x >> node[i].y;
sort(node, node + n, cmp);
j = 0;
s = 1;
for(i = 0; i < n; i++)
{
if(node[i].x >= node[j].y)
{
s++;
j = i;
}
}
printf("%d\n", s);
}
return 0;
}
3、區間覆蓋問題。
具體描述:
用i表示x軸上座標爲[ i - 1, i ]的區間(長度爲1),並給出M(1 <= M <= 200) 個不同的整數,表示M個這樣的區間。
現在讓你畫幾條線段覆蓋住所有的區間,條件是每一條線段可以任意長,但是要求所畫線段之和最小,並且線段的數目不超過N。
分析:
如果N>= M,那麼顯然用M條長度爲1 的線段可以覆蓋住所有的區間,所求的線段總長爲M。
如果N = 1,那麼顯然所需的線段總長爲i(max) - i(min) + 1。
如果N = 2,那麼相當於是在N = 1的情況下從某一個地方斷開。
如果N = k,那麼從間隔最大的兩個部分斷開。
給出書本上面的樣題:HDU 1051 Wooden Sticks(需要使用到標記值,頗費腦子)
HDU 1050 Moving Tables(這道題可以用貪心和樹狀數組來解,樹狀數組還沒有涉及,但是我會回來的......)