• [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;
    }
    
  • 相关阅读:
    Java中的位运算符
    华为2019年NE40E-X8,承诺命令
    华为网络设备修改console密码
    MySQL5.7 多实例
    华为防火墙域间策略全开命令
    Linux基础命令---ntpstat显示时间服务器同步
    【转载】Java程序模拟公安局人员管理系统
    redis cluster集群动态伸缩--删除主从节点
    DBUtils的使用之查询的操作
    服务治理-Resilience4j(限流)
  • 原文地址:https://www.cnblogs.com/jklongint/p/4741132.html
Copyright © 2020-2023  润新知