joshua分享:从第一个节点开始依次进行深度搜索即可,每一步的搜索需要如下满足三个条件!
旅行Ⅱ
http://www.nowcoder.com/questionTerminal/61d1f87753f04f4fbe4d3cee749ca895
joshua分享:从第一个节点开始依次进行深度搜索即可,每一步的搜索都要判断是否合法,
需要满足下面的几个规则:
1. 当前节点没有走过;
2. 当前费用足够当前节点的消费;
3. 当前节点的所有前驱节点都已经走过;
/**
* struct Point {
* int x;
* int y;
* };
*/
class Solution {
public:
int Travel(int N, int V, int* A, int ALen, vector<Point>& list) {
// 有N个节点,就有2^N个状态
vector<int> dp(1<<N, 0);
// 保存每一个节点的前驱节点
vector<vector<int> > pre(N, vector<int>());
for(auto p : list) { pre[p.y-1].push_back(p.x-1); }
int ans = search(pre, A, dp, 0, N, V, 0);
return ans;
}
int search(const vector<vector<int> > &pre,
int *A,
vector<int> &dp,
long long u, int N, int V, int t) {
if(dp[u] != 0) return dp[u];
int tMax = t;
for(int i = 0; i < N; i++) {
// 如果当前 i 节点已经走过或者费用不足,就不需要进行搜索
if( ((1<<i)&u) > 0 || A[i] > V ) continue;
bool status = true;
// 如果当前节点存在某一个前驱节点还没走过,也不能进行该节点的搜索
for(int j : pre[i]) {
if( ((1<<j)&u) == 0 ) {
status = false;
break;
}
}
if(status) {
// 加入当前节点,并继续深度搜索下一个节点
tMax = max(tMax, search(pre, A, dp, u ^ (1<<i), N, V-A[i], t+1));
}
}
// 保存 或者 更新当前节点的状态
dp[u] = tMax;
return tMax;
}
};

