AmazingCounters.com

HDU 5402 : Travelling Salesman Problem

题目大意:n*m的格子,从左上角走到右下角,每个格子只能走一遍,每个格子上有一个非负数,要让途径的数字和最大,最后要输出路径

思路:显然茹果n,m有一个是奇数的话所有格子的数字都能被我吃到,如果都是偶数呢?我把棋盘黑白染色,显然其中染成黑色的点我都是能不取一个,剩下的点我每个都取.

比赛的时候gkp说能不能取两个白色的块反而比只取一个黑色块结果大,想了下是不会的,证明很简单,n,m都是偶数那么黑色块和白色快的数量是相同的,每次只能上下左右走,也就是只能从一个颜色走到另一个颜色,如果能够避开两块或者更多的黑块而不经过白块,那么经过格子的路线必然不能能出现黑白黑白的序列,发现这个后证实了我的想法,比赛时CP敲了这题的代码,下面是我赛后AC的

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #define maxn 5000009
  5 #define ll long long
  6 using namespace std;
  7 const int dx[10]={0,0,0,1,-1};
  8 const int dy[10]={0,1,-1,0,0};
  9 const char di[10]={'0','R','L','D','U'};
 10 int a[400][400],n,m,d=4,visit[400][400];
 11 void dfs(int x,int y,int l,int r,int xt,int yt)
 12 {
 13     if(x==n && y==r)return;
 14     d = (d%4)+1;
 15     visit[x][y] = 1;
 16     for(int i=1;i<=4;i++)
 17     {
 18         int xx = x + dx[i], yy = y + dy[i];
 19         if(xx<1||xx>n||visit[xx][yy]||yy<l || yy > r ||(xx==xt && yy == yt))continue;
 20         printf("%c",di[i]);
 21         dfs(xx,yy,l,r,xt,yt);
 22         d = i;
 23         break;
 24     }
 25 }
 26 int main()
 27 {
 28     while(scanf("%d%d",&n,&m)!=EOF)
 29     {
 30         memset(visit,0,sizeof(visit));
 31         int sum = 0;
 32         for(int i=1;i<=n;i++)
 33         {
 34             for(int j=1;j<=m;j++)
 35             {
 36                 scanf("%d",&a[i][j]);
 37                 sum += a[i][j];
 38             }
 39         }
 40         if(n&1)
 41         {
 42             printf("%d\n",sum);
 43             int u = (n-1)>>1;
 44             while(u--)
 45             {
 46                 for(int i=1;i<m;i++)printf("R");
 47                 printf("D");
 48                 for(int i=1;i<m;i++)printf("L");
 49                 printf("D");
 50             }
 51             for(int i=1;i<m;i++)printf("R");
 52             puts("");
 53         }
 54         else if(m&1)
 55         {
 56             printf("%d\n",sum);
 57             int u = (m-1)>>1;
 58             while(u--)
 59             {
 60                 for(int i=1;i<n;i++)printf("D");
 61                 printf("R");
 62                 for(int i=1;i<n;i++)printf("U");
 63                 printf("R");
 64             }
 65             for(int i=1;i<n;i++)printf("D");
 66             puts("");
 67         }
 68         else
 69         {
 70             int x=0,y=0,minx = 0x3f3f3f3f;
 71             for(int i=1;i<=n;i++)
 72             {
 73                 for(int j=1;j<=m;j++)if((i+j)&1)
 74                 {
 75                     if(minx>a[i][j])
 76                     {
 77                         minx=a[i][j];
 78                         x=i;
 79                         y=j;
 80                     }
 81                 }
 82             }
 83             printf("%d\n",sum-minx);
 84             int u = (y-1)>>1,t=u;
 85             while(t--)
 86             {
 87                 for(int i=1;i<n;i++)printf("D");
 88                 printf("R");
 89                 for(int i=1;i<n;i++)printf("U");
 90                 printf("R");
 91             }
 92             d=4;
 93             dfs(1,u*2+1,u*2+1,u*2+2,x,y);
 94             int v = m-u*2-2;
 95             v>>=1;t=v;
 96             while(t--)
 97             {
 98                 printf("R");
 99                 for(int i=1;i<n;i++)printf("U");
100                 printf("R");
101                 for(int i=1;i<n;i++)printf("D");
102             }
103             puts("");
104         }
105     }
106     return 0;
107 }

 

posted @ 2015-08-18 21:45  philippica  阅读(190)  评论(0编辑  收藏  举报