3 3 2 3 3 3 3 3 3 3 2
25 RRDLLDRR
题意:给你一个n*m的矩阵,每个点都有其对应的值,从(1,1)开始走到(n,m)所能得到的值总和最大是多少?(一个点只能走一次)
分析:恶心模拟。比赛的时候没有模拟出来。神马都是浮云。解法大概和题解的差不多。
(1)如果n*m是奇数,那么所有的点都能走完,路径也很好输出。
(2)如果n*m是偶数,那么就得舍弃一个点,但是并不是所有的点都可以舍弃,只有当点(x,y)满足x*y是奇数的时候才可以舍弃,题意求最大值,那么事先把最小的可删点的值与坐标记录下来,然后跑路径的时候绕过它就好了。假设不走的点是(X,Y),那么:
a)当Y==1时,把1、2列单独拿出来,绕过(X,Y)走完之后,一定是走到了点(n,2),然后往右走一格就进入了右边剩下的n*(m-2)的矩阵,先向上到顶,然后向右一格,向下走到底,向右走一格……依次类推就能走到终点;
b)把第Y-1、Y列单独拿出来,第1~Y-2列可以很好走完,先向下到底,然后向右一格,然后向上到顶,再向右……依次类推,
当Y是偶数时,那么之前最后走到的点是(1,Y-2),向右走一格进入(1,Y-1),然后Y-1、Y两列可以绕过(X,Y)走完,最终走到(n,Y),往右走一格进入右边剩下的n*(m-Y)的矩阵,此时n*(m-Y)是偶数,由于是从左下角进入矩阵的,那么可以,先向上走到顶,向右一格,向下到底……依次类推,一定可达终点;
当Y是奇数时,那么之前最后走到的点是(n,Y-2),向右走一格进入(n,Y-1),然后Y-1、Y两列可以绕过(X,Y)走完,最终走到(1,Y),往右走一格进入右边剩下的n*(m-Y)的矩阵,此时n*(m-Y)是奇数,于是像(1)一样走就好。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5402
代码清单:
#include<set> #include<map> #include<ctime> #include<cmath> #include<queue> #include<stack> #include<cctype> #include<string> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; const int maxn = 100 + 5; int n,m; int X,Y; int data; int main(){ // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(scanf("%d%d",&n,&m)!=EOF){ int ans=0; int minn=100000; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&data); ans+=data; if(((i+j)&1)&&!(i==n&&j==m)){ if(data<minn){ X=i; Y=j; minn=data; } } } } if(n&1){ printf("%d\n",ans); for(int i=0;i<n;i++){ if(i) printf("D"); for(int j=1;j<m;j++){ if(i&1) printf("L"); else printf("R"); } }printf("\n"); } else if(m&1){ printf("%d\n",ans); for(int i=0;i<m;i++){ if(i) printf("R"); for(int j=1;j<n;j++){ if(i&1) printf("U"); else printf("D"); } }printf("\n"); } // n*m是偶数 else{ printf("%d\n",ans-minn); //先把左边n*(Y-2)的矩阵走完 for(int i=0;i<Y-2;i++){ if(i) printf("R"); for(int j=1;j<n;j++){ if(i&1) printf("U"); else printf("D"); } if(i==Y-3) printf("R"); } //当Y是偶数 if(!(Y&1)){ for(int i=1;i<=X;i++){ if(i>1) printf("D"); if(i==X) break; if(i&1) printf("R"); else printf("L"); } for(int i=X+1;i<=n;i++){ printf("D"); if(i&1) printf("L"); else printf("R"); } for(int i=1;i<=m-Y;i++){ printf("R"); for(int j=1;j<n;j++){ if(i&1) printf("U"); else printf("D"); } }printf("\n"); } else{ //当Y==1的情况 if(Y==1){ for(int i=1;i<=X;i++){ if(i>1) printf("D"); if(i==X) break; if(i&1) printf("R"); else printf("L"); } for(int i=X+1;i<=n;i++){ printf("D"); if(i&1) printf("L"); else printf("R"); } Y=Y+1; for(int i=1;i<=m-Y;i++){ printf("R"); for(int j=1;j<n;j++){ if(i&1) printf("U"); else printf("D"); } }printf("\n"); } //当Y是奇数 else{ for(int i=n;i>=X;i--){ if(i<n) printf("U"); if(i==X) break; if(i&1) printf("L"); else printf("R"); } for(int i=X-1;i>=1;i--){ printf("U"); if(i&1) printf("R"); else printf("L"); } for(int i=1;i<=m-Y;i++){ printf("R"); for(int j=1;j<n;j++){ if(i&1) printf("D"); else printf("U"); } }printf("\n"); } } } }return 0; }