啊。。。这道题我一开始的想法是dp,因为我们要求的是在这个区间中和的最大值。
但是没想到只要暴力就好了。
这道题用到了一个著名的想法是:黑白棋盘染色问题。
题意:
现在给你一个n*m的矩阵,然后告诉你每个矩阵中的数字,然后现在要从左上角走到右下角,然后问你所能获得的数字和的最大值是多少。当然,你只能往四个方向走,而且每个点只能走一次。并且叫你输出路径。
思路:
这里我分了三种情况。
1)首先当行或者列数都是1的时候,那么我们就只可能有一种走法(横着走或者是竖着走)然后获取所有的数值。
2)当行数或者是列数其中之一是奇数时,我们肯定能够遍历完这张地图的全部,走法要根据行列奇偶性然后来分情况讨论。
3)这种情况是这道题里面最复杂的一种了。。。我竟然卡了整整一个晚上,我的想法是把每一种情况都分出来,但是实际上不用。
http://blog.youkuaiyun.com/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多校。。。