当前位置: 首页 > wzjs >正文

象山网站优化公司沧州微酷网络科技有限公司

象山网站优化公司,沧州微酷网络科技有限公司,python做网站开发,wordpress remove_query_arg最近准备蓝桥杯 一直在练搜索和图论hhh 题意 给定 n m n \times m nm的数字矩阵 可以取出若干数字 但是有限制 取出的两个数字不能在八联通方向上相邻 数据范围 1 ≤ N , M ≤ 6 , 1 ≤ T ≤ 20 1≤N,M≤6,1≤T≤20 1≤N,M≤6,1≤T≤20 思…

最近准备蓝桥杯 一直在练搜索和图论hhh

题意

给定 n × m n \times m n×m的数字矩阵
可以取出若干数字
但是有限制 取出的两个数字不能在八联通方向上相邻


数据范围

1 ≤ N , M ≤ 6 , 1 ≤ T ≤ 20 1≤N,M≤6,1≤T≤20 1N,M61T20

思路

遍历方式

这道题的dfs方式对我来说是第一次接触
学到很多

本题采取遍历矩阵中的行优先的方式
可以理解为把下面这段常见的双重循环遍历拆成dfs中的坐标一步一步加减

for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)

也就是对于每一行(每一个 x x x)
先把这一行的每一列走完 (先 y y y++)
然后再把 x x x++

如何保证八联通内不相邻?

定义一个别样的 v i s vis vis数组 i n t int int 类型
用来记录 ( i , j ) (i,j) (i,j)这个点八联通范围内有多少个点被选过


如果vis[i][j]==0 对于这个点可以有选和不选两种操作

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define pii pair<int,int>
#define ar2 array<int,2>
#define ar3 array<int,3>
#define ar4 array<int,4>
#define endl '\n'
void cmax(int &a,int b){a=max(a,b);}
void cmin(int &a,int b){a=min(a,b);}
const int N=20,MOD=1e9+7,INF=0x3f3f3f3f,LINF=LLONG_MAX;
int dx[]={1,1,1,0,0,-1,-1,-1};
int dy[]={1,-1,0,1,-1,0,1,-1};int n,m,g[N][N];
int vis[N][N];
int ans=0;void dfs(int x,int y,int sum){if(y==m+1){cmax(ans,sum);dfs(x+1,1,sum);return;}if(x==n+1){cmax(ans,sum);return;}//不选dfs(x,y+1,sum);if(vis[x][y]==0) {//选// vis[x][y]=1;for(int i=0;i<8;i++){int tx=x+dx[i],ty=y+dy[i];if(tx<1||tx>n||ty<1||ty>m) continue;vis[tx][ty]++;}dfs(x,y+1,sum+g[x][y]);// vis[x][y]=0;for(int i=0;i<8;i++){int tx=x+dx[i],ty=y+dy[i];if(tx<1||tx>n||ty<1||ty>m) continue;vis[tx][ty]--;}}
}void solve() {memset(vis,0,sizeof vis);memset(g,0,sizeof g);ans=0;cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>g[i][j];}}dfs(1,1,0);cout<<ans<<endl;}signed main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);int t=1;cin>>t;while (t--) solve();}

代码细节

  • dfs中 在最前面判断完x和y之后
    不要单独判断vis[x][y]==1
if(vis[x][y]){dfs(x,y+1,sum);return;
}

要判断的话就要写成这样 里面会多一次dfs
然后在这个判断过后 再分类讨论选或不选
这样会多很多次递归 会tle

  • 所以要写成上面code这样
  • 先走不选这个dfs 因为无论这个点能不能选 不选这个选项肯定要走一次的
  • 然后也不要判断vis[x][y]!=0 因为会多一次dfs
  • 直接判断vis[x][y]==0 然后 后面写选这个点的情况
	//不选dfs(x,y+1,sum);if(vis[x][y]==0) {//选for(int i=0;i<8;i++){int tx=x+dx[i],ty=y+dy[i];if(tx<1||tx>n||ty<1||ty>m) continue;vis[tx][ty]++;}dfs(x,y+1,sum+g[x][y]);for(int i=0;i<8;i++){int tx=x+dx[i],ty=y+dy[i];if(tx<1||tx>n||ty<1||ty>m) continue;vis[tx][ty]--;}

这样就能减少递归次数
记得回溯

原来错的细节

  • 我一开始把 ( i , j ) (i,j) (i,j)选上后 就把这一块九个点的vis都记为true 然后在dfs中 如果vis[x][y]==1 就更新ans 然后return 并且写了一个check函数 检查这个点八联通范围内有没有vis为true的点 如果有就跳过这个点

  • 这是完全错误的 因为一个点没选 但是它左边的点选了 这个点也会 v i s = = t r u e vis==true vis==true 那么它右边这个点就会因为它的 v i s = = t r u e vis==true vis==true而被跳过

  • 还有 碰到 v i s [ x ] [ y ] = = 1 vis[x][y]==1 vis[x][y]==1时 不应该直接更新ans并且return 因为vis[x][y]==1只代表这个点不能走 不能直接return 应该再找其他的点dfs 然后再return

http://www.dtcms.com/wzjs/818167.html

相关文章:

  • 便宜购 网站建设爱链在线
  • 旅游品牌网站的建设莱芜正规的网站建设
  • 建视频网站的费用深圳百度推广开户
  • c语言做网站可用的ftp网站
  • 广东企业网站seo哪家好怎样用jsp做网站 新手教程
  • 网站 设计 电商自助网站免费建站平台
  • 网站建设方案及深圳蚂蚁网络
  • 镇江网站建设优化案例分析北京游戏软件开发公司
  • 口碑营销方案珠海做网站优化的公司
  • 网站源码小千个人网免费制作app软件教程
  • 河北中保建设集团网站首页增城网站建设服务
  • 网站建设公司的会计分录约么同城实时定位搜索引擎
  • 购物网站建设需求模板下载电子商务平台经营者对
  • 织梦网站访问量统计代码如何创建微信小程序
  • 网站设计开发招聘做网站seo的公司哪家好
  • 云南省工程建设交易系统网站seo站外推广业务外包
  • 福建省分行建设银行网站wordpress 获取标题
  • 装修做劳务去哪个网站找工地做网站架构需要注意什么
  • 怎么做vip电影网站网页设计尺寸多少比较好
  • 临沂网站开发中国建设银行网站登陆
  • 深圳网站建设设软件开发合同书范本
  • 免费网站建站品牌营销是什么
  • 网站备案 多ip东莞网络推广费用
  • 订餐网站开发网站建设技术员工资
  • 平凉市网站建设如何在网站后台备份数据库表
  • 广州手机网站建设报价网站开发及服务器总共多少钱
  • 哈尔滨做网站的oeminc可以做数理化的网站
  • 盈利网站wordpress 可以干嘛
  • 上海松江做网站公司制作灯笼作文
  • 微网站的优缺点济南网络推广公司有哪些