青蛙过河
bool canCross(vector<int>& stones) {
// 题目:河宽被分成一格格,已知某些格有石头。青蛙往前跳,初始跳1步,
// 若上次跳k步、这次跳k-1、k、k+1步。问青蛙能否过河?
// 写法类似bfs,石头当作顶点,jump[i]当作顶点i的出边
unordered_map<int, set<int>> jump; // 某石头=>set{可以跳几步}
jump[0].insert(1);
set<int> st; // 快速判断某位置是否有石头
for (int pos : stones)
st.insert(pos);
for (int pos : stones) { // 遍历有石头的位置
for (int k : jump[pos]) {
int next = pos + k;
if (!st.count(next)) continue;
if (next == stones.back()) return true;
if (k - 1 > 0) jump[next].insert(k - 1);
jump[next].insert(k);
jump[next].insert(k + 1);
}
}
return false;
}
一船每次两人,最少过河时间
按过河时间排序,<=3人的情况单独讨论。>=4人时假设最快a、b,最慢c、d,贪心法目标是先送最慢的两人过去,两种方案:
- a送c、d过去:a送d + a回来 + a送c + a回来,d+a+c+a
- c、d一起过去:ab先过去 + a回来 + cd过去 + b回来,b+a+d+b
那种更快?(1)-(2)=a+c-2b