3 3 2 3 3 3 3 3 3 3 2
25 RRDLLDRR
题意:现有一个n*m的迷宫(n行m列),每一个格子都有一个非负整数,Teacher Mai想要从迷宫的左上角(1,1)到迷宫的右下角(n,m),并且使得他走过的路径的整数之和最大,问最大和为多少以及他走的路径。
放上出题人的解题报告解题思路:首先,因为每个格子都是非负整数,而且规定每个格子只能走一次,所以为了使和尽可能大,必定是走的格子数越多越好。这样我们就需要考虑一下是不是所有的格子都可以走。
在纸上画画,你就会发现,若n、m中至少有一个是奇数的话,必然能够遍历每一个格子,这样的话,我们只需往n、m中为偶数的那个方向先走就可以了
若n、m都为偶数的话,根据棋盘黑白染色(关于棋盘黑白染色问题,想了解的可以点链接)可以得知,当假设(1,1)与(n,m)都为黑色,那么这条路径势必黑色格子数会比白色格子数多1,而棋盘中黑白格子数是相等的,所以棋盘中有一个白格子不会被经过
或许你自己在研究这道题的时候,会感觉有点混乱,总想着删值最小的格子,但有些格子删了,会有好几个格子走不到,那是因为删了黑格子的缘故,那样导致黑白格子数差2,又要有两个白格子无法到达,这样和势必会比只删一个白格子要来得小。
所以只能删白格子
其他的在此不再细讲,可以看出题人的解题报告,如果需要我对一些细节进行补充的话,也可以提出来
暂时先放上几组数据以供参考
3 4
2 3 3 3
3 3 3 3
3 3 3 3
35
RRRDLLLDRRR
4 3
2 3 3
3 3 3
3 3 3
3 3 3
35
DDDRUUURDDD
4 4
3 2 3 3
3 3 3 3
3 3 3 3
3 3 3 3
45
DRRURDDLLLDRRR
4 4
3 3 3 3
3 3 3 3
3 2 3 3
3 3 3 3
45
RRRDLLLDDRRURD
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<math.h> #include<vector> #include<map> #include<set> #include<stdlib.h> #include<cmath> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 105; const int inf = 1000000000; const int mod = 1000000007; int s[N][N]; int main() { int n,m,i,j,sum,x,y; while(~scanf("%d%d",&n,&m)) { sum=0;x=1,y=2; for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&s[i][j]); sum+=s[i][j]; if(((i+j)&1)&&s[x][y]>s[i][j]) x=i,y=j; } if(n&1||m&1) { printf("%d\n",sum); if(n&1) { for(i=1;i<=n;i++) { for(j=1;j<m;j++) if(i&1) printf("R"); else printf("L"); if(i<n) printf("D"); else puts(""); } } else { for(i=1;i<=m;i++) { for(j=1;j<n;j++) if(i&1) printf("D"); else printf("U"); if(i<m) printf("R"); else puts(""); } } } else { printf("%d\n",sum-s[x][y]); for(i=1;i<=n;i+=2) { if(x==i||x==i+1) { for(j=1;j<y;j++) { if(j&1) printf("D"); else printf("U"); printf("R"); } if(y<m) printf("R"); for(j=y+1;j<=m;j++) { if(j&1) printf("U"); else printf("D"); if(j<m) printf("R"); } if(i<n-1) printf("D"); } else if(x<i) { for(j=1;j<m;j++) printf("L"); printf("D"); for(j=1;j<m;j++) printf("R"); if(i<n-1) printf("D"); } else { for(j=1;j<m;j++) printf("R"); printf("D"); for(j=1;j<m;j++) printf("L"); printf("D"); } } puts(""); } } return 0; }菜鸟成长记