启发式搜索
本页面将简要介绍启发式搜索及其用法。
简介¶
启发式搜索(英文:heuristic search)是一种改进的搜索算法。它在普通搜索算法的基础上引入了启发式函数,该函数的作用是基于已有的信息对搜索的每一个分支选择都做估价,进而选择分支。简单来说,启发式搜索就是对取和不取都做分析,从中选取更优解或删去无效解。
例题¶
由于概念过于抽象,这里使用例题讲解。
「NOIP2005 普及组」采药
题目大意:有
解题思路
我们写一个估价函数
估价函数
我们在取的时候判断一下是不是超过了规定体积(可行性剪枝);在不取的时候判断一下不取这个时,剩下的药所有的价值 + 现有的价值是否大于目前找到的最优解(最优性剪枝)。
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include <algorithm>
#include <cstdio>
using namespace std;
const int N = 105;
int n, m, ans;
struct Node {
int a, b; // a 代表时间,b 代表价值
double f;
} node[N];
bool operator<(Node p, Node q) { return p.f > q.f; }
int f(int t, int v) { //计算在当前时间下,剩余物品的最大价值
int tot = 0;
for (int i = 1; t + i <= n; i++)
if (v >= node[t + i].a) {
v -= node[t + i].a;
tot += node[t + i].b;
} else
return (int)(tot + v * node[t + i].f);
return tot;
}
void work(int t, int p, int v) {
ans = max(ans, v);
if (t > n) return; //边界条件:只有n种物品
if (f(t, p) + v > ans) work(t + 1, p, v); //最优性剪枝
if (node[t].a <= p) work(t + 1, p - node[t].a, v + node[t].b); //可行性剪枝
}
int main() {
scanf("%d %d", &m, &n);
for (int i = 1; i <= n; i++) {
scanf("%d %d", &node[i].a, &node[i].b);
node[i].f = 1.0 * node[i].b / node[i].a; // f为性价比
}
sort(node + 1, node + n + 1); //根据性价比排序
work(1, m, 0);
printf("%d\n", ans);
return 0;
}
|
build本页面最近更新:,更新历史
edit发现错误?想一起完善? 在 GitHub 上编辑此页!
people本页面贡献者:OI-wiki
copyright本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用