问题描述:
已知一个n*n的矩阵,从左上角出发到右下角,每次只能往右走一步,或者往下走一步,请设计一个程序输出走到右下角终点时走过的数和的最大值。
搜索与回溯算法框架:
框架1:
框架2:
代码1:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
const int n=4;
int G[n][n];
int maxsum=0;
int tsum=0;
//假设下为x 右为y
int dx[]={1,0} ; //向下走一步 x+1 y 不变
int dy[]={0,1} ;//向右走一步y+1 x不变
void find_maxsum(int x,int y){
for(int i=0;i<2;++i){
int x1=x+dx[i];
int y1=y+dy[i];
bool t1=(x1==n-1)&&(y1==n-1);//到达终点
bool t2=(x1<=n-1)&&(y<=n-1);//点在有效范围内,包括终点
if(t2)
{
tsum+=G[x1][y1];
if(t1) {
maxsum=max(maxsum,tsum);//更新最大值
}
else find_maxsum(x1,y1);//递归
tsum-=G[x1][y1];//回溯
}
}
}
int main(){
srand(time(0)); //随机数
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
G[i][j]=rand()%2;
}
}
G[0][0]=0;
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
cout<<G[i][j]<<' ';
}
cout<<endl;
}
find_maxsum(0,0);
cout<<maxsum<<endl;
return 0;
}
代码2:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
const int n = 4;
int G[n][n];
int maxsum = 0;
int tsum = 0;
void dfs(int x, int y) {
// 基本情况:到达右下角的单元格
if (x == n - 1 && y == n - 1) {
tsum += G[x][y];
maxsum = max(maxsum, tsum);
tsum -= G[x][y]; // 回溯,探索其他路径
return;
}
tsum += G[x][y];
// 向下探索
if (x + 1 < n)
dfs(x + 1, y);
// 向右探索
if (y + 1 < n)
dfs(x, y + 1);
tsum -= G[x][y]; // 回溯,探索其他路径
}
int main() {
srand(time(0));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
G[i][j] = rand() % 2;
}
}
G[0][0]=0;
cout << "生成的矩阵:" << endl;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
cout << G[i][j] << ' ';
}
cout << endl;
}
dfs(0, 0);
cout << "最大和: " << maxsum << endl;
return 0;
}
输出结果: