[动态规划] 蛇行序列(snake sequence)

来源:互联网 发布:工商信息查询网大数据 编辑:程序博客网 时间:2024/04/30 13:23
You are given a grid of numbers. A snake sequence is made up of adjacent numbers such that for each number, the number on the right or the number below it is +1 or -1 its value. For example, 1 3 2 6 8 -9 7 1 -1 2 1 5 0 1 9 In this grid, (3, 2, 1, 0, 1) is a snake sequence. 

昨天朋友问我这样一道面试题,第一感觉是用DFS,后来想了一下其实用DP效率跟高,以下是DP方程(相连是指亮点之间可以走动)

/*F(i,j) = 1 + max(f(i-1,j),f(i,j-1)) 如果P(i,j) 跟P(i-1,j),P(i,j-1)都相连       = 1 + f(i-1,j)    如果P(i,j)跟P(i-1,j)相连       = 1 + f(i,j - 1)  如果P(i,j) 跟P(i,j-1)都相连       = 1  如果P(i,j) 跟P(i-1,j),P(i,j-1)都不相连*/


#include <vector>#include <iostream>#include <algorithm>#include <iterator>using namespace std;/*You are given a grid of numbers. A snake sequence is made up of adjacent numbers such that for each number, the number on the right or the number below it is +1 or -1 its value. For example, 1 3 2 6 8 -9 7 1 -1 2 1 5 0 1 9 In this grid, (3, 2, 1, 0, 1) is a snake sequence. F(i,j) = 1 + max(f(i-1,j),f(i,j-1)) 如果P(i,j) 跟P(i-1,j),P(i,j-1)都相连       = 1 + f(i-1,j)   如果P(i,j)跟P(i-1,j)相连       = 1 + f(i,j - 1) 如果P(i,j) 跟P(i,j-1)都相连       = 1 如果P(i,j) 跟P(i-1,j),P(i,j-1)都不相连*/bool IsConnect(int a,int b){return a == (b +1) || a == (b -1);}void DFSGenResult(int i,int j,vector<vector<int> > const & grid,vector<vector<int> > const & flags,vector<vector<int> > & result,vector<int> &arr){arr.push_back(grid[i][j]);if(flags[i][j] == 1){result.push_back(vector<int>(arr.rbegin(),arr.rend()));arr.resize(arr.size() -1);return;}int left_j = j -1;int up_i = i - 1;if(left_j >= 0 && IsConnect(grid[i][j] , grid[i][left_j]) && (flags[i][j] == flags[i][left_j]+1)){DFSGenResult(i,left_j,grid,flags,result,arr);}if (up_i >= 0 && IsConnect(grid[i][j], grid[up_i][j]) && (flags[i][j] == flags[up_i][j]+1)){DFSGenResult(up_i,j,grid,flags,result,arr);}arr.resize(arr.size() -1);}vector<vector<int> > SnakeSequence(vector<vector<int> > const & grid){size_t size_n = grid.size();size_t size_m = grid[0].size();int max_len = 1;vector<vector<int> > flags(size_n);for(size_t i =0; i < size_n; ++i){flags[i].resize(size_m,1);}for( size_t i = 1; i < size_m; ++i){if(IsConnect(grid[0][i],grid[0][i-1])){flags[0][i] = flags[0][i-1] + 1;}}for( size_t i = 1; i < size_n; ++i){if(IsConnect(grid[i][0],grid[i -1][0])){flags[i][0] = flags[i-1][0] + 1;}}for(size_t i = 1; i < size_n; ++i){for(size_t j = 2; j < size_m; ++j){int & val = flags[i][j];if(IsConnect(grid[i][j],grid[i-1][j])){if(IsConnect(grid[i][j],grid[i][j -1])){val = max(flags[i][j-1],flags[i-1][j]) + 1;}else{val = flags[i -1][j] +1;}if(val > max_len){max_len = val;}}else if(IsConnect(grid[i][j],grid[i][j -1])){val = flags[i][j -1] +1;if(val > max_len){max_len = val;}}}}vector<vector<int> > arrResult;for(size_t i = 1; i < size_n; ++i){for(size_t j = 2; j < size_m; ++j){if(flags[i][j] == max_len){vector<int> arr;DFSGenResult(i,j,grid,flags,arrResult,arr);}}}return arrResult;}void Test_SnakeSequence(){size_t n = 0,m =0;cin >>n>>m;vector<vector<int> > grid;grid.reserve(n);for(size_t i = 0; i < n; ++i){vector<int> input(m);copy_n(istream_iterator<int>(cin),m,input.begin());grid.push_back(input);}vector<vector<int> > result = SnakeSequence(grid);for(vector<vector<int> >::iterator it = result.begin(); it != result.end(); ++it){cout<<endl;copy(it->begin(),it->end(),(ostream_iterator<int>(cout," "))); }}

0 0