【HDU 5402】Travelling Salesman Problem(構造)
阿新 • • 發佈:2019-01-28
被某題卡SB了,結果這題也沒讀好。。。以為每個格子可以有負數就當搜尋做了,怎麼想也搜不過去,後來發現每個格子是非負數,那麼肯定就是構造題。
題解如下:
首先如果n為奇數或者m為奇數,那麼顯然可以遍歷整個棋盤。
如果n,m都為偶數,那麼講棋盤黑白染色,假設(1,1)和(n,m)都為黑色,那麼這條路徑中黑格個數比白格個數多1,而棋盤中黑白格子個數相同,所以必然有一個白格不會被經過,所以選擇白格中權值最小的不經過。
構造方法是這樣,首先RRRRDLLLLD這樣的路徑走到這個格子所在行或者上一行,然後DRUR這樣走到這個格子的所在列或者前一列,然後繞過這個格子。然後走完這兩行,接著按LLLLDRRRR這樣的路徑往下走。
這題需要說明一下為什麼這麼選,因為如果你選的不是 (i,j)互為奇偶的格子的話,肯定有其餘的(i,j)互為奇偶的格子不能被走到,如果選擇的話,只有這一個格子不會被走到,所以根據貪心肯定要選這個格子了.
恩。。挺腦洞的一題,寫起來倒是不難。
#include<cstdio> #include<algorithm> using namespace std; const int maxn = 105; const int INF = (1 << 30); int mat[maxn][maxn]; int n,m,sum,minv,posx,posy; void special_solve(){ printf("%d\n",sum - minv); if(!(posx & 1)){ for(int i = 0; i < posx; i++){ char c = i & 1 ? 'L' : 'R'; for(int j = 1; j < m; j++) printf("%c",c); printf("D"); } int base = 0; for(int i = 0; i < m; i++){ char c = (i + base) & 1 ? 'U' : 'D'; if(i != posy) printf("%c",c); else base ++; if(i < m - 1) printf("R"); } for(int i = posx + 2; i < n; i++){ printf("D"); char c = i & 1 ? 'R' : 'L'; for(int j = 1; j < m; j++) printf("%c",c); } } else{ for(int i = 0; i < posx - 1; i++){ char c = i & 1 ? 'L' : 'R'; for(int j = 1; j < m; j++) printf("%c",c); printf("D"); } int base = 0; for(int i = 0; i < m; i++){ char c = (i + base) & 1 ? 'U' : 'D'; if(i != posy) printf("%c",c); else base ++; if(i < m - 1) printf("R"); } for(int i = posx + 1; i < n; i++){ printf("D"); char c = i & 1 ? 'R' : 'L'; for(int j = 1; j < m; j++) printf("%c",c); } } } int main(){ while(scanf("%d%d",&n,&m) != EOF){ sum = 0; minv = INF; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++){ scanf("%d",&mat[i][j]); sum += mat[i][j]; if((i + j) & 1){ if(minv > mat[i][j]){ posx = i; posy = j; minv = mat[i][j]; } } } if(n & 1){ printf("%d\n",sum); for(int i = 0; i < n; i++){ char c = i & 1 ? 'L' : 'R'; for(int j = 1; j < m; j++) printf("%c",c); if(i != n - 1) printf("D"); } } else if(m & 1){ printf("%d\n",sum); for(int i = 0; i < m; i++){ char c = i & 1 ? 'U' : 'D'; for(int j = 1; j < n; j++) printf("%c",c); if(i != m - 1) printf("R"); } } else special_solve(); puts(""); } return 0; }