啊。。。这道题我一开始的想法是dp,因为我们要求的是在这个区间中和的最大值。
但是没想到只要暴力就好了。
这道题用到了一个著名的想法是:黑白棋盘染色问题。
题意:
现在给你一个n*m的矩阵,然后告诉你每个矩阵中的数字,然后现在要从左上角走到右下角,然后问你所能获得的数字和的最大值是多少。当然,你只能往四个方向走,而且每个点只能走一次。并且叫你输出路径。
思路:
这里我分了三种情况。
1)首先当行或者列数都是1的时候,那么我们就只可能有一种走法(横着走或者是竖着走)然后获取所有的数值。
2)当行数或者是列数其中之一是奇数时,我们肯定能够遍历完这张地图的全部,走法要根据行列奇偶性然后来分情况讨论。
3)这种情况是这道题里面最复杂的一种了。。。我竟然卡了整整一个晚上,我的想法是把每一种情况都分出来,但是实际上不用。
http://blog.csdn.net/queuelovestack/article/details/47756605 (借鉴了这里的思路)
我们只需在白块中找到一个值最小的,然后不走就好了。
那么怎么绕过去呢?想法就是在走到这一行或是那个点的上一行时,用S型的姿势绕过去,相当于这样子是一下子就走了两行,注意一下绕过去之后的L与R的选择就好。
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<vector> using namespace std; #define maxn 111 #define inf 99999999 int a[maxn][maxn]; int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ memset(a,0,sizeof(a)); int 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(n==1){ printf("%d\n",sum); for(int i=1;i<m;i++) printf("R"); puts(""); } else if(m==1){ printf("%d\n",sum); for(int i=1;i<n;i++) printf("D"); puts(""); } else if(n%2||m%2){ printf("%d\n",sum); if(n%2){ //列是偶数; for(int i=1;i<=n;i++){ for(int j=1;j<m;j++){ if(i%2){ printf("R"); } else printf("L"); } if(i!=n) printf("D"); } } else{ //行是偶数; for(int i=1;i<=m;i++){ for(int j=1;j<n;j++){ if(i%2){ printf("D"); } else printf("U"); } if(i!=m) printf("R"); } } } //以上都是对的! else{ int tx=0,ty=0; int ans=inf; //下面的目的是为了找到在白块中数值最小的那个点的坐标; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(i%2){ if(j%2==0){ if(ans>a[i][j]){ ans=a[i][j]; tx=i; ty=j; } } } else if(i%2==0){ if(j%2){ if(ans>a[i][j]){ ans=a[i][j]; tx=i; ty=j; } } } } } printf("%d\n",sum-ans); //printf("%d %d\n",tx,ty); for(int i=1;i<=n;i+=2){ if(i==tx||i+1==tx){ for(int j=1;j<ty;j++){ if(j&1) printf("D"); else printf("U"); printf("R"); } if(ty<m) printf("R"); for(int j=ty+1;j<=m;j++){ if(j&1) printf("U"); else printf("D"); if(j<m) printf("R"); } if(tx<n-1) printf("D"); } else if(tx<i){ for(int j=1;j<m;j++){ printf("L"); } printf("D"); for(int j=1;j<m;j++){ printf("R"); } if(i<n-1) printf("D"); } else{ for(int j=1;j<m;j++){ printf("R"); } printf("D"); for(int j=1;j<m;j++){ printf("L"); } printf("D"); } } } printf("\n"); } }
orz多校。。。
版权声明:本文为博主原创文章,未经博主允许不得转载。
hdu(5402)——Travelling Salesman Problem(模拟题)
原文地址:http://blog.csdn.net/acmer_hades/article/details/47779929