Dynamic Programming series

来源:互联网 发布:windows10 mysql 启动 编辑:程序博客网 时间:2024/06/01 07:12

DP is absolutely the best way to category levels of programming..... and it is always the favourite questions being asked by FB or Google.

1: Entry Level DP problem.    

/*  A sequence of numbers is called a zig-zag sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a zig-zag sequence.For example, 1,7,4,9,2,5 is a zig-zag sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, 1,4,7,2,5 and 1,7,4,5,5 are not zig-zag sequences, the first because its first two differences are positive and the second because its last difference is zero.Given a sequence of integers, sequence, return the length of the longest subsequence of sequence that is a zig-zag sequence. A subsequence is obtained by deleting some number of elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.*/#include "header.h"using namespace std;int longestZigzagSequence(vector<int>& nums) {  int n = nums.size();  vector<int> end_positive(n, 0);  vector<int> end_negative(n, 0);  for(int i = 0; i < nums.size(); ++i) {    end_positive[i] = 1;    end_negative[i] = 1;    for(int j = 0; j <= i; ++j) {      if(nums[j] > nums[i]) end_negative[i] = max(end_positive[j]+1, end_negative[i]);      if(nums[i] > nums[j]) end_positive[i] = max(end_negative[j]+1, end_positive[i]);    }  }  return max(end_negative[n-1], end_positive[n-1]);}int main(void) {  vector<int> nums{1, 17, 5, 10, 13, 15, 10, 5, 16, 8};  vector<int> test{ 70, 55, 13, 2, 99, 2, 80, 80, 80, 80, 100, 19, 7, 5, 5, 5, 1000, 32, 32 };  cout << longestZigzagSequence(test) << endl;}

// Same as rob neighbours in LeetCode 

/*The old song declares "Go ahead and hate your neighbor", and the residents of Onetinville have taken those words to heart. Every resident hates his next-door neighbors on both sides. Nobody is willing to live farther away from the town's well than his neighbors, so the town has been arranged in a big circle around the well. Unfortunately, the town's well is in disrepair and needs to be restored. You have been hired to collect donations for the Save Our Well fund.Each of the town's residents is willing to donate a certain amount, as specified in the int[] donations, which is listed in clockwise order around the well. However, nobody is willing to contribute to a fund to which his neighbor has also contributed. Next-door neighbors are always listed consecutively in donations, except that the first and last entries in donations are also for next-door neighbors. You must calculate and return the maximum amount of donations that can be collected.*/#include "header.h"using namespace std;int maxDonations(vector<int>& nums) {  if(nums.size() == 0) return 0;  int n = nums.size();  if(n == 1) return nums[0];  if(n == 2) return max(nums[0], nums[1]);  vector<int> donations_odd(n, 0);  vector<int> donations_even(n, 0);  donations_odd[0] = nums[0];  donations_even[1] = nums[1];  for(int i = 2; i < n - 1; ++i) {    donations_odd[i] = max(donations_odd[i-2] + nums[i], donations_odd[i-1]);  }  for(int i = 3; i < n; ++i) {    donations_even[i] = max(donations_even[i-2] + nums[i], donations_even[i-1]);  }  return max(donations_even[n-1], donations_odd[n-2]);}int main(void) {  vector<int> nums{94, 40, 49, 65, 21, 21, 106, 80, 92, 81, 679, 4, 61,  6, 237, 12, 72, 74, 29, 95, 265, 35, 47, 1, 61, 397,  52, 72, 37, 51, 1, 81, 45, 435, 7, 36, 57, 86, 81, 72};  cout << maxDonations(nums) << endl;}

Medium Level

Top Coder:  ChessMetric

It is very straight forward to first come up with dfs searching.

struct Pair {  int _x;  int _y;  Pair(int x, int y) : _x(x), _y(y) {}};void waysToMove(int matrixSize, Pair start, Pair end, int steps, long long& method) {  if(start._x < 0 || start._x >= matrixSize || start._y < 0 || start._y >= matrixSize) return;  if(end._x < 0 || end._x >= matrixSize || end._y < 0 || end._y >= matrixSize || steps < 0) return;  if((steps == 0) && (start._x == end._x) && (start._y == end._y)) {    method++;    return;  }  waysToMove(matrixSize, Pair(start._x - 1, start._y), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x + 1, start._y), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x, start._y + 1), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x, start._y - 1), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x + 1, start._y + 1), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x + 1, start._y - 1), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x - 1, start._y - 1), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x - 1, start._y + 1), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x - 1, start._y + 2), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x - 1, start._y - 2), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x + 1, start._y - 2), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x + 1, start._y + 2), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x - 2, start._y - 1), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x - 2, start._y + 1), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x + 2, start._y - 1), end, steps - 1, method);  waysToMove(matrixSize, Pair(start._x + 2, start._y + 1), end, steps - 1, method);}


Apparently, we can just use DP to solve it.

class ChessMetric {public:long long howMany( int size, vector <int> start, vector <int> end, int numMoves ) {this->size = size;map[0][start[0]][start[1]] = 1;for(int mv = 1; mv <= numMoves; ++mv) {for(int i = 0; i < size; ++i) {for(int j = 0; j < size; ++j) {map[mv][i][j] = neigh_sum(mv-1,i,j);}}}return map[numMoves][end[0]][end[1]];}private:int size;const vector<pair<int,int>> ds = {{ 0, 1}, { 1, 0}, { 0,-1}, {-1, 0},  { 1, 1}, {-1, 1}, { 1,-1}, {-1,-1},   { 1, 2}, { 2, 1}, {-1, 2}, {-2, 1},  { 1,-2}, { 2,-1}, {-1,-2}, {-2,-1}};long long neigh_sum(int mv, int i, int j) {long long total = 0;for(auto delta:ds) {int x = i + delta.first;int y = j + delta.second;if(inbound(x,y)) {total += map[mv][x][y];}}return total;}bool inbound(int i, int j) {return 0 <= i && i < size && 0 <= j && j < size;}};

1: https://www.topcoder.com/community/data-science/data-science-tutorials/dynamic-programming-from-novice-to-advanced/

0 0
原创粉丝点击