大致题意:n*m的非负数矩阵,从(1,1) 只能向四面走,一直走到(n,m)为终点,路径的权就是数的和,输出一条权值最大的路径方案
思路:由于这是非负数,要是有负数就是神题了,要是n,m中有一个是奇数,显然可以遍历,要是有一个偶数,可以画图发现,把图染成二分图后,(1,1)为黑色,总能有一种构造方式可以只绕过任何一个白色的点,然后再遍历其他点,而绕过黑色的点必然还要绕过两个白色点才能遍历全部点,这是画图发现的,所以找一个权值最小的白色点绕过就可以了,
题解给出了证明:
如果n,m都为偶数,那么讲棋盘黑白染色,假设(1,1)和(n,m)都为黑色,那么这条路径中黑格个数比白格个数多1,而棋盘中黑白格子个数相同,所以必然有一个白格不会被经过,所以选择白格中权值最小的不经过。
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <cstring> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <string> #include <vector> #include <cstdio> #include <ctime> #include <bitset> #include <algorithm> #define SZ(x) ((int)(x).size()) #define ALL(v) (v).begin(), (v).end() #define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i) #define reveach(i, v) for (__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++ i) #define REP(i,n) for ( int i=1; i<=int(n); i++ ) #define rep(i,n) for ( int i=0; i< int(n); i++ ) using namespace std; typedef long long ll; #define X first #define Y second typedef pair<int,int> pii; template <class T> inline bool RD(T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void PT(T x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) PT(x / 10); putchar(x % 10 + '0'); } const int N = 123; int mp[N][N]; int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ int sum = 0; memset(mp,0,sizeof(mp)); REP(i,n) REP(j,m) RD(mp[i][j]), sum += mp[i][j]; if( (n&1)||(m&1) ){ PT(sum);puts(""); if( n&1 ){ REP(r,n){ if( r&1 ) REP(i,m-1) putchar('R'); else REP(i,m-1) putchar('L'); if( r != n) putchar('D'); } }else{ REP(c,m){ if( c&1 ) REP(i,n-1) putchar('D'); else REP(i,n-1) putchar('U'); if( c != m) putchar('R'); } } }else{ int minn = 1LL<<30; int sx,sy; REP(x,n) REP(y,m){ if( (x+y)&1 ){ if( mp[x][y] < minn) minn = mp[x][y], sx = x,sy = y; } } printf("%d\n",sum-minn); bool ok = 0; REP(y,m){ if( (y-1)/2+1 == (sy-1)/2+1){ ok = 1; bool rgt = 1; REP(x,n){ if( x == sx) { if( x != n) putchar('D'); continue; } if( rgt) putchar('R'); else putchar('L'); if( x != n) putchar('D'); rgt = !rgt; } y++; }else{ if( ((y&1)&&ok==0) || ((y%2 == 0)&&ok) ){ REP(x,n-1) putchar('D'); }else{ REP(x,n-1) putchar('U'); } } if( y != m) putchar('R'); } } puts(""); } }
3 3 2 3 3 3 3 3 3 3 2
25 RRDLLDRR