标签:选择 mem sizeof 答案 nal 就会 方向 fir amp
题意:给一个n行m列矩阵 从第一列任意一个位置出发 每次往右 右上 右下三个方向走一格 直到最后一列 输出所类和的最小值和路径!! 最小值相同则输出字典序最小路径
很像一开始介绍的三角形dp 很明显用dp来做
但是输出路径非常麻烦
要使路径为最小字典序 对三个方向进行选择时 应该从小到大 这样就会是最小字典序
我一开始用一维的next数组 这样答案是不连续的 可能从1跳到5
应该用二维的next数组!!!!
#include<bits/stdc++.h> using namespace std; #define N 2000+5 #define inf 0x3f3f3f3f int n,m; int dp[N][N]; int next1[N][N]; int mp[N][N]; int first; int main() { while(scanf("%d%d",&n,&m)==2&&(m+n)) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&mp[i][j]); int ans=inf; memset(next1 ,0,sizeof next1); for(int i=1;i<=n;i++) dp[i][m]=mp[i][m]; for(int j=m-1;j>=1;j--) for(int i=1;i<=n;i++) { int dic[3]={i-1,i,i+1}; if(i==1)dic[0]=n; if(i==n)dic[2]=1; sort(dic,dic+3); dp[i][j]=inf; for(int k=0;k<3;k++) { if(dp[i][j]>mp[i][j]+dp[dic[k] ][j+1]) { dp[i][j]=mp[i][j]+dp[dic[k] ][j+1]; next1[i][j]=dic[k]; } if(j==1) { if(ans>dp[i][j]) { ans=dp[i][j]; first=i; } } } } printf("%d",first); for(int i=next1[first][1],j=2;j<=m;i=next1[i][j],j++) printf( " %d",i); printf("\n%d\n",ans); } return 0; }
标签:选择 mem sizeof 答案 nal 就会 方向 fir amp
原文地址:https://www.cnblogs.com/bxd123/p/10451192.html