当前位置: 首页 > 知识库问答 >
问题:

网格行走高分

赵志
2023-03-14

有一个有趣的游戏叫一个人游戏。它在M*n网格上播放。每个网格单元格中都有一个非负整数。你从0分开始。不能输入含有整数0的单元格。你可以在你想要的任何单元格开始和结束游戏(当然单元格中的数字不能是0)。在每一步中,您可以向上、向下、向左和向右移动到相邻的网格单元格。你最后能得到的分数是你路径上的数字之和。但每个单元格最多只能输入一次。

游戏的目的是让你的分数尽可能高。

输入:
第一行输入是一个整数t测试用例的数量。每个测试用例的第一行是包含2个整数mn,这是网格中的行和列数。接下来的M行中的每一行都包含N空格分隔的整数D,指示相应单元格中的数字

4
1 1
5911
1 2
10832 0
1 1
0
4 1
0
8955
0
11493
5911
10832
0
11493

我试过了,但是我的方法对于7x7的网格来说非常慢。我试图递归地访问网格的每一个可能的路径,并比较每一个路径的总和。下面是我的代码

#include<iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;

int max(int a,int b,int c, int d)
{
int max = a;
if(b>max)
    max = b;
if(c>max)
    max = c;
if(d>max)
    max = d;
return max;
}

int Visit_Component( int (*A)[8], int Visit[8][8], int m,int n , int row, int col)
{

if ( ( row >= m ) || (col >= n )  || (col < 0) || (row < 0)  || A[row][col] == 0         || Visit[row][col] == 1 )
{
    return 0;
}
else
{

    Visit[row][col] = 1;
    int a= 0,b=0,c=0,d=0,result =0;
    a = Visit_Component( A, Visit,m,n, row+1, col);
    b = Visit_Component( A, Visit,m,n, row, col +1);
    c = Visit_Component( A, Visit,m,n, row, col -1);
    d = Visit_Component( A, Visit,m,n, row-1, col );
    Visit[row][col] = 0;
    result  = A[row][col] + max(a,b,c,d);
    return result;
}
}

int main(){

int T;
scanf("%d",&T);
for(int k =0; k<T;k++)
{
    int N ;
    int M;
    int count = 0;
    int maxcount = 0;
    scanf("%d %d",&M,&N);
    int C[8][8];
    int visit[8][8];
    for(int i = 0; i < M; i++)
        for(int j = 0; j < N; j++)
        {
            scanf("%d",&C[i][j]);
            visit[i][j] = 0;
        }
    for( int i= 0 ; i< M ; i++ )
    {
        for( int j =0; j< N ; j++ )
        {

            count  = Visit_Component( C, visit,M,N, i, j);
            if(count > maxcount)
            {
                maxcount  = count;
            }
        }
    }
    printf("%d\n",maxcount);
}
return 0;
}

请建议我如何优化这种方法或更好的算法。

共有1个答案

燕扬
2023-03-14

正如维基百科关于旅行推销员问题的文章所建议的那样,有精确的算法,可以快速解决这个问题。但很难找到任何。它们很可能很复杂。

至于优化OP的方法,有几种可能性。

从简单的微优化开始比较容易:conditionvisite[row][col]==1满足概率最高,所以应该放在第一位。

#include<iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;

int max(int a,int b,int c, int d)
{
  int max = a;
  if(b>max)
    max = b;
  if(c>max)
    max = c;
  if(d>max)
    max = d;
  return max;
}

typedef unsigned long long ull;
static const int HS = 10000019;
static const int HL = 20;
struct HT {
  ull v;
  int r;
  int c;
};
HT ht[HS] = {0};

int Visit_Component(
  int (*A)[8], ull& Visit, int m,int n , int row, int col, int x)
{

  if ( (Visit & (1ull << (8*row+col))) || ( row >= m ) || (col >= n )  ||
    (col < 0) || (row < 0)  || A[row][col] == 0)
  {
    return 0;
  }
  else
  {
    if (x < HL)
    {
      HT& h = ht[(Visit+4*row+col)%HS];
      if (h.v == Visit && h.r == row && h.c == col)
        return 0;
    }

    Visit |= (1ull << (8*row+col));
    int a= 0,b=0,c=0,d=0,result =0;
    a = Visit_Component( A, Visit,m,n, row+1, col, x+1);
    b = Visit_Component( A, Visit,m,n, row, col +1, x+1);
    c = Visit_Component( A, Visit,m,n, row, col -1, x+1);
    d = Visit_Component( A, Visit,m,n, row-1, col , x+1);
    Visit &= ~(1ull << (8*row+col));
    result  = A[row][col] + max(a,b,c,d);

    if (x < HL)
    {
      HT& h = ht[(Visit+4*row+col)%HS];
      h.v = Visit;
      h.r = row;
      h.c = col;
    }

    return result;
  }
}

int main(){

  int T;
  scanf("%d",&T);
  for(int k =0; k<T;k++)
  {
    int N ;
    int M;
    int count = 0;
    int maxcount = 0;
    scanf("%d %d",&M,&N);
    int C[8][8];
    ull visit = 0;
    for(int i = 0; i < M; i++)
        for(int j = 0; j < N; j++)
        {
            scanf("%d",&C[i][j]);
        }
    for( int i= 0 ; i< M ; i++ )
    {
        for( int j =0; j< N ; j++ )
        {

            count  = Visit_Component( C, visit,M,N, i, j, 0);
            if(count > maxcount)
            {
                maxcount  = count;
            }
        }
    }
    printf("%d\n",maxcount);
  }
  return 0;
}
 类似资料:
  • 问题内容: 我认为使用Flexbox无法实现这一点,因为每一行只能是适合其元素的最小高度,但是可以使用更新的CSS Grid来实现吗? 明确地说,我希望网格中所有行的所有元素的高度相等,而不仅仅是每行。基本上,最高的“单元格”应规定所有单元格的高度,而不仅仅是其行中的单元格。 问题答案: 简短答案 如果目标是创建具有相等高度的行的网格,而网格中最高的单元格将设置所有行的高度,那么这是一种快速简单的

  • 我认为使用Flexbox是不可能实现这一点的,因为每一行只能是适合其元素所需的最小高度,但使用较新的CSS网格可以实现这一点吗? 明确地说,我希望网格中的所有元素在所有行上的高度相等,而不仅仅是每一行。基本上,最高的“单元格”应该指示所有单元格的高度,而不仅仅是其行中的单元格。

  • 我目前正在做一个项目,我找不到任何解决方案。我希望Gridpane行的高度从该行中一个特定列的宽度动态计算。整个Gridpane必须可调整大小,其余可用空间应位于下面的另一行,以便根据该单元格内的元素保留该单元格的纵横比。孩子们,有什么想法吗? 我希望单元格1,0和1,1可以调整大小,并且通过增加其宽度,可以清楚地看到第0行和第1行的高度不应该平均增加。如果还剩下任何高度,我希望第3行可以承受,因

  • 我在我的应用程序中使用了Vaadin Flow 14.6.2,材料主题和自定义CSS样式。当加载网格时,如果单元格的内容包装了5次,则网格最初加载时,网格行重叠,从而截断包含包装数据的单元格中的信息。查看CSS,这是由于CSS“Transform:translateY(#px)”设置在网格的TR(row)标记上太小。作为参考点,网格在第二行放置了一个76像素的translateY。 有重叠行的网格

  • 我正在尝试制作一个网格,它有7列,并以所需的行数进行扩展(由后端提供)。所以我的css是这样的: null null 我试图实现的是一个网格,有一个定义的较小的第一行72px,然后所有其他行应该是86px……但它就是不起作用,有没有解决这种情况的办法?使用上面的片段使我的第三行达到73.23px

  • 我想在Vaadin 11的网格中实现自动换行。据我所知,你需要为此做两件事: < li >设置相应单元格的样式。 < li >增加行高。 我使用以下代码完成了第一步: productsGrid.addColumn(TemplateRenderer.of(“[[item.name]]”).withProperty(“name”,产品::getName)).setHeader(“name”); 现在我