基本思想 :
在对问题求解时,总是做出在当前看来是最好的选择. 也就是说, 不从整体最优上加以考虑, 他所做出的仅是在某种意义上的局部最优解.
特点和使用:
贪心算法不是对所有问题都能得到整体最优解, 但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解.
步骤:
1 把求解的问题分为若干个子问题
2 对每个子问题求解, 得到子问题的局部最优化解
3 把子问题的解局部最优解合成原来解问题的一个解
1 活动安排
#include<iostream>
#define MAX 11
using namespace std;
void print(int* indata, int size)
{
for(int i = 0; i < size; i++)
std::cout<<indata[i]<<endl;
}
/* s 活动开始时间 f 结束时间 按结束时间递增排列 */
int greedsct(int* s, int* f ,int* b, int size)
{
int count = 1;
int j = 1;
b[0] = true;
for(int i = 1; i < size; i++)
{
if(s[i] >= f[j]) // 优先安排先结束的活动
{
b[i] = true;
j = i;
count ++;
}
else
{
b[i] = false;
}
}
return count;
}
int main(void)
{
int s[MAX] = {1, 3, 0, 5, 3, 5, 6, 8, 8, 2 ,12};
int f[MAX] = {4, 5 ,6, 7, 8, 9, 10, 11, 12, 13, 14}; /* 结束时间递增排序*/
int b[MAX] = {0};
int c = greedsct(s, f, b, MAX);
print(b, MAX);
return 0;
}
2 马踏棋盘
#include<iostream>
#define MAXB 8
#define MAXD 8
using namespace std;
int board[MAXB][MAXB];
int dx[MAXD] = {-2,-1,1,2,-2,-1,1,2};
int dy[MAXD] = {-1,-2,-2,-1,1,2,2,1};
void print(int** indata, int h, int w)
{
for(int i = 0; i < h; i++)
{
for(int j = 0; j < w; j++)
std::cout<< *((int*)indata + i * w + j) << " ";
std::cout<<std::endl;
}
}
/* 计算当前节点可以踏出的正确方向个数 */
int way(int x, int y)
{
int count = 0, tx, ty;
if(x < 0 || y < 0 || x >= MAXB || y >= MAXB || board[y][x] != 0) return -1; //非法节点或已经走过
for(int i = 0; i < MAXD; i++)
{
tx = x + dx[i];
ty = y + dy[i];
if(tx < 0 || ty < 0 || tx >= MAXB || ty >= MAXB)
continue; // 该节点非法 遍历下一个方向
if(board[ty][tx] == 0)
{
count++; // 此方向未走过
}
}
return count;
}
/* 逐步求解 */
void move(int x, int y, int count)
{
int max = MAXD + 1, dn = -1, tx, ty;
if (count >= MAXB * MAXB)
{
return; // 遍历完退出
}
for(int i = 0; i < MAXD; i++)
{
tx = x + dx[i];
ty = y + dy[i];
if(tx < 0 || ty < 0 || tx >= MAXB || ty >= MAXB || board[ty][tx] != 0)
continue; // 该节点非法 遍历下一个方向
if(count == MAXB * MAXB - 1)
{
count = MAXB * MAXB;
board[ty][tx] = count;
return; // 最后一个节点特殊处理
}
int wn = way(tx, ty);
if(wn < max && wn > 0)
{
max = wn;
dn = i;
}
}
if(dn >= 0 && dn < MAXD)
{
tx = x + dx[dn];
ty = y + dy[dn];
board[ty][tx] = count + 1;
count = count + 1;
move(tx, ty, count);
}
}
int main(void)
{
board[0][0] = 1;
move(0,0,1);
print((int**)board, MAXB, MAXB);
}