0
点赞
收藏
分享

微信扫一扫

[算法课]图选数字


文章目录

  • ​​更新​​
  • ​​题目来源 网络​​
  • ​​算法标签 递归​​
  • ​​题目描述​​
  • ​​思路​​
  • ​​时间复杂度​​
  • ​​正确答案​​
  • ​​题目代码​​
  • ​​做法1​​
  • ​​做法二​​

更新

手贱加了个else,
实际上这里被我搞成走一个可能,而不是两个
数列再回溯上来之后进到下一个dfs的时候因为else的关系直接被跳过
所以说这个时候的状态2实际直接被跳了

正确答案 749

题目来源 网络

算法标签 递归

题目描述

在一个由 n 行 m 列的方格组成的地图上,每个方格上有一个数,你要取出一些数,使得他们的和值最大。
但是有一个条件,你选取的数中,任意 2 个数所在的方格都不能相邻。
2 个方格相邻就是指他们共享一条边。

48, 30, 39, 87,
48, 91, 90, 22,
36, 60, 41, 28,
49, 96, 37, 88,
87, 71, 96, 66,
15, 24, 75, 55

说明:如果挑了91,则30和48和90和60是不能挑的!

思路

爆搜找所有符合条件的序列,比较序列大小,输出最大序列和

时间复杂度

正确答案

749

题目代码

做法1

#include<iostream>
using namespace std;

int n, m;
int num[10][10];
bool st[10][10];
int dx[4] = { -1,0,1,0 }, dy[4] = { 0,1,0,-1 };
int ans, s;

int Max(int a,int b){return a>b?a:b;}
int a[6][4] = { 48, 30, 39, 87,
48, 91, 90, 22,
36, 60, 41, 28,
49, 96, 37, 88,
87, 71, 96, 66,
15, 24, 75, 55
};

void dfs(int x, int y)
{
if (y == m)x++, y=0;
if (x == n) {ans = Max(ans, s);return;}

bool flag = true;
for (int i = 0; i < 4; i++)
{
int tx = dx[i] + x, ty = dy[i] + y;
if (tx<0&&tx>n&&ty<0&&ty>m)continue;
if (st[tx][ty]) { flag = false; break; }
}

if (flag)
{
s += a[x][y];
st[x][y] = true;
dfs(x, y+1);
st[x][y] = false;
s -= a[x][y];
}

dfs(x, y+1);
}
int main()
{
n = 6, m = 4;

dfs(0, 0);

cout << ans;

return 0;
}

做法二

从1,1开始起始,不用判断偏移量时的边界问题
从1,1开始相当于其他部分全部用为走过来判断。

#include<iostream>

using namespace std;

int n, m;
int num[10][10];
bool st[12][12];

int ans, s;

int Max(int a,int b){return a>b?a:b;}
int a[7][5] = { 0, 0, 0, 0, 0,
0,48, 30, 39, 87,
0,48, 91, 90, 22,
0,36, 60, 41, 28,
0,49, 96, 37, 88,
0,87, 71, 96, 66,
0,15, 24, 75, 55
};

bool check(int x,int y){return (!st[x+1][y]&&!st[x][y+1]&&!st[x-1][y]&&!st[x][y-1])? true:false;}
void dfs(int x, int y,int s)
{
if (y == m+1)y = 0, x++;
if (x == n+1) {ans = Max(ans, s);return;}

if (check(x,y))
{
st[x][y] = true;
dfs(x, y+1,s+a[x][y]);
st[x][y] = false;
}

dfs(x, y+1,s);
}

int main()
{
n = 6, m = 4;

dfs(1, 1,0);

cout << ans;

return 0;
}


举报

相关推荐

0 条评论