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 }