hdu5402 Travelling Salesman Problem

Problem Description
Teacher Mai is in a maze with  n  rows and  m  columns. There is a non-negative number in each cell. Teacher Mai wants to walk from the top left corner  (1,1)  to the bottom right corner  (n,m) . He can choose one direction and walk to this adjacent cell. However, he can't go out of the maze, and he can't visit a cell more than once.

Teacher Mai wants to maximize the sum of numbers in his path. And you need to print this path.
 

Input
There are multiple test cases.

For each test case, the first line contains two numbers  n,m(1n,m100,nm2) .

In following  n  lines, each line contains  m  numbers. The  j -th number in the  i -th line means the number in the cell  (i,j) . Every number in the cell is not more than  104 .
 

Output
For each test case, in the first line, you should print the maximum sum.

In the next line you should print a string consisting of "L","R","U" and "D", which represents the path you find. If you are in the cell  (x,y) , "L" means you walk to cell  (x,y1) , "R" means you walk to cell  (x,y+1) , "U" means you walk to cell  (x1,y) , "D" means you walk to cell  (x+1,y) .
 

Sample Input
   
   
   
   
3 3 2 3 3 3 3 3 3 3 2
 

Sample Output
   
   
   
   
25 RRDLLDRR

第一想法是搜多,但看到100*100的大小,感觉不是搜索题,后来发现是模拟题。如果n或m有一个是奇数,那么一定可以把所有的点都走一遍,这样结果一定是最大的,所以只要考虑都是偶数的情况。我的思路是先把横纵坐标只和为奇数的染成黑色,偶数的染成白色,那么画图可以知道

如果选择一个黑色方格不走,那么其他点都能够走一遍,但如果选择一个白色方格不走,必须要不走另外两个黑色方格才能走到终点,所以 一定是选择最小的黑色方格数不走。

然后选出最小的黑色方格,然后模拟一下走法就行了。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;
#define inf 99999999
int gra[106][106],n,m,sum;
void jishulu()
{
    int i,j;
    printf("%d\n",sum);
    if(n%2==1){
        for(i=1;i<=n;i++){
            for(j=1;j<=m-1;j++){
                printf("%c",i%2==1?'R':'L');
            }
            if(i<n)printf("D");
            else printf("\n");
        }
    }
    else{
        for(j=1;j<=m;j++){
            for(i=1;i<=n-1;i++){
                printf("%c",j%2==1?'D':'U');
            }
            if(j<m)printf("R");
            else printf("\n");
        }
    }
}

void oushulu()
{
    int i,j,minx=inf,dx=0,dy=0,x,y;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            if((i+j)%2==1 && minx>gra[i][j]){
                dx=i;dy=j;minx=gra[i][j];
            }
        }
    }
    printf("%d\n",sum-minx);
    if(dx==n){
        for(i=1;i<=n-2;i++){
            for(j=1;j<=m-1;j++){
                printf("%c",i%2==1?'R':'L');
            }
            printf("D");
        }
        if(dy==1){
            x=n-1;y=1;
            while(1)
            {
                printf("RD");x++;y++;
                if(x==n && y==m){
                    printf("\n");break;
                }
                printf("RU");x--;y++;
            }
        }
        else{
            printf("D");
            x=n;y=1;
            while(1)
            {
                printf("RU");
                x--;y++;
                if(x+1==dx && y+1==dy){
                    printf("RRD");x++;y+=2;
                }
                else{
                    printf("RD");x++;y++;
                }
                if(x==n && y==m){
                    printf("\n");break;
                }
            }
        }
    }
    else if(dx!=n){
        for(i=1;i<=dx-1;i++){
            for(j=1;j<=m-1;j++){
                printf("%c",i%2==1?'R':'L');
            }
            printf("D");
        }
        if(dx%2==1){
           printf("D");
           x=dx+1;y=1;
           if(dy==m){
              while(1)
              {
                  if((y+1)!=m){
                    printf("RURD");y+=2;
                  }
                  else{
                     printf("R");y++;
                     if(x!=n)printf("D");break;
                  }
              }
           }
           else{
              while(1)
              {
                if(x-1==dx && y+1==dy){
                   printf("RRURD");y+=3;
                }
                else{
                   printf("RURD");y+=2;
                }
                if(y==m){
                    if(x!=n)printf("D");
                    break;
                }
              }
           }
           for(i=dx+2;i<=n;i++){
              for(j=1;j<=m-1;j++){
                 printf("%c",i%2==1?'L':'R');
              }
              if(i!=n)printf("D");
           }
           printf("\n");

        }
        else if(dx%2==0){
            printf("D");
            x=dx+1;y=m;
            if(dy==1){
              while(1)
              {
                  if((y-1)!=1){
                    printf("LULD");y-=2;
                  }
                  else{
                     printf("L");y--;
                     if(x!=n)printf("D");
                     break;
                  }
              }
           }
           else{
              while(1)
              {
                if(x-1==dx && y-1==dy){
                   printf("LLULD");y-=3;
                }
                else{
                   printf("LULD");y-=2;
                }
                if(y==1){
                    if(x!=n)printf("D");
                    break;
                }
              }
           }
           if(x!=n){
              for(i=dx+2;i<=n;i++){
                 for(j=1;j<=m-1;j++){
                   printf("%c",i%2==1?'L':'R');
                 }
                 if(i!=n)
                 printf("D");
              }
           }
           printf("\n");

        }
    }
}

int main()
{
    int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        sum=0;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                scanf("%d",&gra[i][j]);
                sum+=gra[i][j];
            }
        }
        if(n%2==1 || m%2==1){
            jishulu();
        }
        else oushulu();
    }
    return 0;
}


你可能感兴趣的:(模拟,HDU,多校)