[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; } |