多校第九场Travelling Salesman Problem总结

来源:互联网 发布:admui 源码下载 编辑:程序博客网 时间:2024/05/16 11:41

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5402

题意:n*m的矩阵格子,每个格子有相应的数字,上要从矩阵的左上角走到右下角,要求使得走过的数字之和尽可能多,同时每个格只能走一次,输出走过的数字之和,以及路径

思路:对于n,m任何一个是奇数,那么就能经过所有的格子,如果n,m两个数都是偶数,那么那么讲棋盘黑白染色,假设(1,1)和(n,m)都为黑色,那么这条路径中黑格个数比白格个数多1,而棋盘中黑白格子个数相同,所以必然有一个白格不会被经过,所以选择白格中权值最小的不经过。
构造方法是这样,首先RRRRDLLLLD这样的路径走到这个格子所在行或者上一行,然后DRUR这样走到这个格子的所在列或者前一列,然后绕过这个格子。然后走完这两行,接着按LLLLDRRRR这样的路径往下走。

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-8)
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
const int maxn = 100005;
int a[111][111];
int main()
{
    int n,m;
    int x,y;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int mi=inf;
        ll sum=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
        {
            scanf("%d",&a[i][j]);
            sum+=a[i][j];
            if((i+j)%2==1)
            {
               if(a[i][j]<mi)
               {
                   mi=a[i][j];
                x=i;
                y=j;
               }
            }
        }
        if(n%2==1)
        {
            printf("%lld\n",sum);
            for(int i=1;i<=n;i++)
            {
                if(i%2)
                    for(int j=2;j<=m;j++)printf("R");
                else
                    for(int j=2;j<=m;j++)printf("L");
                if(i!=n)
                        printf("D");
            }
            printf("\n");
        }
        else if(m%2)
        {
            printf("%lld\n",sum);
            for(int i=1;i<=m;i++)
            {
                if(i%2)
                    for(int j=2;j<=n;j++)printf("D");
                else
                    for(int j=2;j<=n;j++)printf("U");
                if(i!=m)
                        printf("R");
            }
            printf("\n");
        }
        else
        {
           printf("%lld\n",sum-mi);
          for(int i=1;i<(x+1)/2;i++)
          {
                    for(int j=2;j<=m;j++)printf("R");
                      printf("D");
                    for(int j=2;j<=m;j++)printf("L");
                        printf("D");
          }
          for(int i=1;i<(y+1)/2;i++)
              printf("DRUR");
          if(x%2)
            printf("DR");
           else
            printf("RD");
        for(int i=(y+1)/2;i<m/2;i++)
            printf("RURD");
        for(int i=(x+1)/2;i<n/2;i++)
          {
               printf("D");
                    for(int j=2;j<=m;j++)printf("L");
                printf("D");
                    for(int j=2;j<=m;j++)printf("R");
          }
          printf("\n");
        }
    }
    return 0;
}
/*
4 4
2 2 2 2
1 2 2 2
2 2 2 2
2 2 2 2
4 4
2 1 2 2
2 2 2 2
2 2 2 2
2 2 2 2
4 4
2 2 2 1
2 2 2 2
2 2 2 2
2 2 2 2
4 4
2 2 2 2
2 2 1 2
2 2 2 2
2 2 2 2
4 4
2 2 2 2
2 2 2 2
2 1 2 2
2 2 2 2
4 4
2 2 2 2
2 2 2 2
2 2 2 1
2 2 2 2
4 4
2 2 2 2
2 2 2 2
2 2 2 2
1 2 2 2
*/

 咦咦咦~wa了一发之后,试了几乎所有的样例、、、

0 0
原创粉丝点击