動態規劃——Unidirectional TSP UVA
阿新 • • 發佈:2018-12-17
題解:
單向TSP,通過上一步的狀態推出下一步的狀態,和數字三角形的想法是一樣的
紫書上解釋挺詳細了,這裡不用遞迴來做的話,由前往後推是不行的,因為要字典序最小,如果從前往後推的話是找不出來的(不信可以試一下)
以後弄dp都從後往前推穩定一點
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; int n,m; int block[15][110]; int dp[15][110],fro[15][110]; int re_num(int pos, int lr) { pos += lr; if(pos <= 0) return n; if(pos > n) return 1; return pos; } int main() { //freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&m) == 2) { memset(fro,0,sizeof(fro)); for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { scanf("%d",&block[i][j]); } } memset(dp,inf,sizeof(dp)); for(int i = 1; i <= n; i++) dp[i][m] = block[i][m]; for(int j = m-1; j >= 1; j--) { //每例 for(int i = 1; i <= n; i++) { //每行 for(int k = -1; k <= 1; k++) { int num = re_num(i,k); if(dp[i][j] > dp[num][j+1]+block[i][j] || (dp[i][j]==dp[num][j+1]+block[i][j]&&fro[i][j]>num)) { dp[i][j] = dp[num][j+1]+block[i][j]; fro[i][j] = num; } } } } int r,minn = inf; for(int i = 1; i <= n; i++) if(minn > dp[i][1]) { r = i; minn = dp[i][1]; } int l = 1; for(int i = r; i != 0; i = fro[i][l++]) { if(l != 1) printf(" "); printf("%d",i); } printf("\n%d\n",minn); } return 0; }