算法导论:动态规划中一道习题的实现

来源:互联网 发布:欧菲斯办公软件 编辑:程序博客网 时间:2024/06/06 15:00

这几日正好在看《算法导论》,对其中的一道习题做了C实现,题目详见220页,第15-6题。

动态规划的基本思想就是降低问题的规模,通过迭代或者递归的方式求解子问题,自底向上推出目标结果。

cipher感觉动态规划就是遵守问题约束的穷举,计算规模自然比较小。

基本思路就是:

M[ i, j ] = p( i, j ) + max( M[ i - 1, j - 1 ], M[ i - 1, j ], M[ i -1, j + 1 ] )
M表示每走一步的获利, p表示每个格子的利润(实现中随机生成),M[ i, j ]可能来自于他的左下方、下放和右下方中最大的一个。

下面给出代码,定义了一个6*6的棋盘:

#include <iostream>#include <stdlib.h>#include <time.h>#define N 6using namespace std;// 递归获得路径void reprintPath( char path[][ N ], int i, int j ) {  int temp = j;  if( i < 0 ) {    cout << i + 1 << ", " << j << endl;  } else {    if( path[ i ][ j ] == 'L' )      temp = j - 1;    if( path[ i ][ j ] == 'R' )      temp = j + 1;    reprintPath( path, i - 1, temp );    cout << i + 1 << ", " << j << endl;  }}// 迭代获得路径void printPath( char path[][ N ], int i, int j ) {  for( int m = i; i >= 0; -- i ) {    cout << "Path " << i + 1 <<       " ( " << i + 1 << ", " << j << " )" << endl;        if( path[ i ][ j ] == 'L' ) {      -- j;    }    if( path[ i ][ j ] == 'R' ) {      ++ j;    }  }  cout << "Path " << i + 1 << " ( " << i + 1 << ", " << j << " )" << endl;}int main(){  // srand( time( NULL ) );  int board[ N ][ N ];  char path[ N - 1 ][ N ];  int tempValue = 0;  char tempPath ='N';  int flag = 0;  // 随机生成每个各自的获利  for( int i = 0; i != N; ++ i ) {    for( int j = 0; j != N; ++ j ) {      board[ i ][ j ] = rand() % 10 + 1;    }  }  // 初始化path数组,该数组用来获得路径  for( int i = 0; i != N - 1; ++ i ) {    for( int j = 0; j != N; ++ j ) {      path[ i ][ j ] = 'N';    }  }    for( int i = 0; i != N; ++ i ) {    for( int j = 0; j != N; ++ j ) {      cout << board[ i ][ j ] << " ";    }    cout << endl;  }  // 循环从1开始,第一行不做考虑  for( int i = 1; i != N; ++ i ) {    // 第一列只有两种情况    if( board[ i - 1 ][ 0 ] >= board[ i - 1 ][ 1 ] ) {      board[ i ][ 0 ] += board[ i - 1 ][ 0 ];      path[ i - 1 ][ 0 ] = 'U';    } else {      board[ i ][ 0 ] += board[ i - 1 ][ 1 ];      path[ i - 1 ][ 0 ] = 'R';    }    // 第2到N-2列有三种情况    for( int j = 1; j != N - 1; ++ j ) {      if( board[ i - 1 ][ j - 1 ] >= board[ i - 1 ][ j ]  ) {tempValue = board[ i - 1 ][ j - 1 ];tempPath = 'L';      } else {tempValue = board[ i - 1 ][ j ];tempPath = 'U';      }      if( tempValue >= board[ i - 1 ][ j + 1 ] ) {board[ i ][ j ] += tempValue;path[ i - 1 ][ j ] = tempPath;      } else {board[ i ][ j ] += board[ i - 1 ][ j + 1 ];path[ i - 1 ][ j ] = 'R';      }          }    // N-1列的两种情况    if( board[ i - 1 ][ N - 1 ] >= board[ i - 1 ][ N - 2 ] ) {      board[ i ][ N - 1 ] += board[ i - 1 ][ N - 1 ];      path[ i - 1 ][ N - 1 ] = 'U';    } else {      board[ i ][ N - 1 ] += board[ i - 1 ][ N - 2 ];      path[ i - 1 ][ N - 1 ] = 'L';    }  }  for( int i = 0; i != N; ++ i ) {    for( int j = 0; j != N; ++ j ) {      cout << board[ i ][ j ] << " ";    }    cout << endl;  }  for( int i = 0; i != N - 1; ++ i ) {    for( int j = 0; j != N; ++ j ) {      cout << path[ i ][ j ] << " ";    }    cout << endl;  }  tempValue = 0;  for( int i = 0; i != N; ++ i ) {    if( tempValue < board[ 5 ][ i ] ) {      tempValue = board[ 5 ][ i ];      flag = i;    }  }  printPath( path, 4, flag );  reprintPath( path, 4, flag );  cout << "the bigest one -> " << flag << endl;}