[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\n", 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(‘\n‘);
}

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\n", 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(‘\n‘);
}

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;
}
时间: 2024-10-20 02:48:19

[hdu5402 Travelling Salesman Problem]YY的相关文章

hdu5402 Travelling Salesman Problem(棋盘染色+模拟)

题目: Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 906    Accepted Submission(s): 331 Special Judge Problem Description Teacher Mai is in a maze with n rows and m c

hdu5402 Travelling Salesman Problem

Problem Description Teacher Mai is in a maze with n rows and m columns. There is a non-negative number in each cell. Teacher Mai wants to walk from the top left corner (1,1) to the bottom right corner (n,m). He can choose one direction and walk to th

构造 - HDU 5402 Travelling Salesman Problem

Travelling Salesman Problem Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5402 Mean: 现有一个n*m的迷宫,每一个格子都有一个非负整数,从迷宫的左上角(1,1)到迷宫的右下角(n,m),并且使得他走过的路径的整数之和最大,问最大和为多少以及他走的路径. analyse: 首先,因为每个格子都是非负整数,而且规定每个格子只能走一次,所以为了使和尽可能大,必定是走的格子数越多越好.这样我们就需

HDOJ 5402 Travelling Salesman Problem 模拟

行数或列数为奇数就能够所有走完. 行数和列数都是偶数,能够选择空出一个(x+y)为奇数的点. 假设要空出一个(x+y)为偶数的点,则必须空出其它(x+y)为奇数的点 Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 747    Accepted Submission(s): 272

多校9 1007 Travelling Salesman Problem

Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 829    Accepted Submission(s): 182Special Judge Problem Description Teacher Mai is in a maze with n rows and m columns

【HDOJ 5402】Travelling Salesman Problem

[HDOJ 5402]Travelling Salesman Problem 一开始以为是搜索 仔细画了画发现就一模拟 奇数行或奇数列的时候怎么走都能全走完 偶数行偶数列的时候就要挑了 . * . * . * * . * . * . . * . * . * * . * . * . 以4*6为例(如上图 星号可以保证不取其中一个可遍历完全图 点好的话就会连带一些星号 所以绕过星号中的最小值 是最佳遍历方式 输入的时候找到最小值并记录下行列 遍历到改行前以 右走到头 下 左走到头 下 右走到头这种方

HDU 5402 Travelling Salesman Problem (模拟 有规律)

Travelling Salesman Problem Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 568    Accepted Submission(s): 200 Special Judge Problem Description Teacher Mai is in a maze with n rows and m colum

HDU 5402 Travelling Salesman Problem (构造)(好题)

大致题意:n*m的非负数矩阵,从(1,1) 只能向四面走,一直走到(n,m)为终点,路径的权就是数的和,输出一条权值最大的路径方案 思路:由于这是非负数,要是有负数就是神题了,要是n,m中有一个是奇数,显然可以遍历,要是有一个偶数,可以画图发现,把图染成二分图后,(1,1)为黑色,总能有一种构造方式可以只绕过任何一个白色的点,然后再遍历其他点,而绕过黑色的点必然还要绕过两个白色点才能遍历全部点,这是画图发现的,所以找一个权值最小的白色点绕过就可以了, 题解给出了证明: 如果n,mn,m都为偶数,

PAT 甲级 1150 Travelling Salesman Problem

https://pintia.cn/problem-sets/994805342720868352/problems/1038430013544464384 The "travelling salesman problem" asks the following question: "Given a list of cities and the distances between each pair of cities, what is the shortest possib