题意,给一个数字矩阵,要求从上往下的一条路径,使这条路径上数字之和最小,如有多条输出最靠右的一条。
数字三角形打印路径。。。
一般打印路径有两种选择,一是转移的时候加以记录,二是通过检查dp值回溯。
#include<cstdio> #include<cstring> #include<vector> using namespace std; const int maxn = 100; int g[maxn+2][maxn]; int d[maxn+2][maxn]; int pa[maxn+2][maxn]; int m,n; const int INF = 1e9; void init(){ memset(*pa,-1,sizeof(*pa)); for(int i = 0; i < maxn; i++) d[i][0] = INF; } vector<int> ans; void print_ans(int s){ ans.clear(); ans.push_back(s); for(int i = m-1; i > 0; i--){ s = pa[i][s]; ans.push_back(s); } for(int i = ans.size()-1; i > 0 ;i--){ printf("%d ",ans[i]); } printf("%d ",ans[0]); } void work() { for(int i = 1; i <= n; i++ ) d[0][i] = g[0][i]; for(int i = 0; i < m; i++){ d[i][n+1] = INF; } for(int i = 1; i < m ;i++){ for(int j = 1; j <= n ; ++j ){ int Min = -1; for(int k = 0; k <=1; k++){ if(d[i-1][j+k] <= d[i-1][j+Min]){ Min = k; } } pa[i][j] = j+Min; d[i][j] = d[i-1][j+Min] + g[i][j]; } } int Min = 0; for(int i = 1; i <= n; i++ ){ if(d[m-1][Min] >= d[m-1][i]){ Min = i; } } print_ans(Min); } int main() { int T; init(); scanf("%d",&T); for(int i = 1; i <= T; i++){ printf("Case %d ",i); scanf("%d%d",&m,&n); for(int i = 0; i < m; i++) for(int j = 1; j <= n; j++) scanf("%d",g[i]+j); work(); } return 0; }