[hdu5402 Travelling Salesman Problem]YY

题意:给一个n*m的矩形,每个格子有一个非负数,求一条从(1,1)到(n,m)的路径(不能经过重复的格子),使得经过的数的和最大,输出具体的方案

思路:对于row为奇数的情况,一行行扫下来即可全部走完得到最大和,对于col为奇数的情况一列列扫即可。对于行和列全部为偶数的情况,将所有格子进行黑白染色,起点和终点的颜色一样,而路径上的颜色是交替的,说明总有一个点不能走到,枚举得到不可到点上的最小值,总和减去就是答案。具体的方案构造方法如下:由于只有一个格子被挖掉不能走,考虑整行或整列的走,走完这个格子前面的所有格子,然后把后面的两行或两列走完,这两行或两列相当于一行或一列,那么整个图相当于是奇数行或奇数列的图了,往后走一定可以遍历完。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#pragma comment(linker, "/STACK:10240000")
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define X                   first
#define Y                   second
#define pb                  push_back
#define mp                  make_pair
#define all(a)              (a).begin(), (a).end()
#define fillchar(a, x)      memset(a, x, sizeof(a))
#define copy(a, b)          memcpy(a, b, sizeof(a))

typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull;

//#ifndef ONLINE_JUDGE
void RI(vector<int>&a,int n){a.resize(n);for(int i=0;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?1:-1;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
//#endif
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}

const double PI = acos(-1.0);
const int INF = 1e9 + 7;
const double EPS = 1e-12;

/* -------------------------------------------------------------------------------- */

int n, m, sum;
int a[102][102];

void out() {
    printf("%d
", sum);
    if (n & 1) {
        char ch = 'R';
        for (int i = 0; i < n; i ++) {
            for (int j = 1; j < m; j ++) putchar(ch);
            if (i < n - 1) putchar('D');
            ch = ch == 'L'? 'R' : 'L';
        }
    }
    else {
        char ch = 'D';
        for (int j = 0; j < m; j ++) {
            for (int i = 1; i < n; i ++) putchar(ch);
            if (j < m - 1) putchar('R');
            ch = ch == 'D'? 'U' : 'D';
        }
    }
    putchar('
');
}

void work() {
    int minnum = INF, x, y;
    for (int i = 0; i < n; i ++) {
        for (int j = 0; j < m; j ++) {
            bool r = i & 1, c = j & 1;
            if ((r == c)) continue;
            if (umin(minnum, a[i][j])) {
                x = i;
                y = j;
            }
        }
    }
    printf("%d
", sum - minnum);
    if (x & 1) {
        char ch = 'D';
        for (int j = 0; j < y; j ++) {
            for (int i = 1; i < n; i ++) putchar(ch);
            putchar('R');
            ch = ch == 'D'? 'U' : 'D';
        }
        ch = 'R';
        for (int i = 0; i < x; i ++) {
            putchar(ch);
            putchar('D');
            ch = ch == 'L'? 'R' : 'L';
        }
        for (int i = x + 1; i < n; i ++) {
            putchar('D');
            putchar(ch);
            ch = ch == 'L'? 'R' : 'L';
        }
        if (y < m - 2) {
            putchar('R');
            ch = 'U';
            for (int j = y + 2; j < m; j ++) {
                for (int i = 1; i < n; i ++) putchar(ch);
                if (j < m - 1) putchar('R');
                ch = ch == 'D'? 'U' : 'D';
            }
        }
    }
    else {
        char ch = 'R';
        for (int i = 0; i < x; i ++) {
            for (int j = 1; j < m; j ++) putchar(ch);
            putchar('D');
            ch = ch == 'R'? 'L' : 'R';
        }
        ch = 'D';
        for (int j = 0; j < y; j ++) {
            putchar(ch);
            putchar('R');
            ch = ch == 'U'? 'D' : 'U';
        }
        for (int j = y + 1; j < m; j ++) {
            putchar('R');
            putchar(ch);
            ch = ch == 'U'? 'D' : 'U';
        }
        if (x < n - 2) {
            putchar('D');
            ch = 'L';
            for (int i = x + 2; i < n; i ++) {
                for (int j = 1; j < m; j ++) putchar(ch);
                if (i < n - 1) putchar('D');
                ch = ch == 'R'? 'L' : 'R';
            }
        }
    }
    putchar('
');
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
    while (cin >> n >> m) {
        sum = 0;
        for (int i = 0; i < n; i ++) {
            for (int j = 0; j < m; j ++) {
                scanf("%d", &a[i][j]);
                sum += a[i][j];
            }
        }
        if (n % 2 || m % 2) out();
        else work();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jklongint/p/4741132.html