URAL - 1029 dp
题意:
n层楼,每层楼有m个房间。找出一个路径从第一层到达第M层,使得路径上的所有数的和是所有可达路径中最小的,每次上到下一层以后就不能再上去,依次输出路径上的各点在所在层的列数。
题解:
参考链接:传送门
dp[i][j]表示:在第i层楼,第j个房间所消耗的最小花费
dp[i][j]的最优值只能从dp[i-1][j]或者dp[i][j-1]或者dp[i][j+1]来得出,所以dp转移方程
1 for(LL i=2; i<=n; ++i) 2 { 3 for(LL j=1; j<=m; ++j) 4 { 5 if(dp[i][j-1]<dp[i-1][j]) 6 { 7 pre[i][j]='L'; //pre数组来记录路径 8 dp[i][j]=dp[i][j-1]+val[i][j]; //dp[i][j]最优由左边的dp[i][j-1]得出 9 } 10 else 11 { 12 pre[i][j]='D'; 13 dp[i][j]=dp[i-1][j]+val[i][j]; //dp[i][j]最优由下面dp[i-1]【j】得出 14 } 15 } 16 for(LL j=m; j>=1; --j) 17 { 18 if(dp[i][j+1]+val[i][j]<dp[i][j]) 19 { 20 pre[i][j]='R'; 21 dp[i][j]=dp[i][j+1]+val[i][j]; 22 } 23 } 24 }
AC代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 #include<math.h> 6 #include<vector> 7 #include<queue> 8 #include<stack> 9 #include<map> 10 using namespace std; 11 typedef long long LL; 12 const int maxn=505; 13 const LL MAX=1e15; 14 const int INF=0x3f3f3f3f; 15 const double eps=1e-8; 16 const double PI=3.1415926; 17 const int mod = 1e9+7; 18 LL val[505][505],dp[505][505],v[505]; 19 char pre[505][505]; 20 LL n,m; 21 int main() 22 { 23 while(~scanf("%lld%lld",&n,&m)) 24 { 25 for(LL i=1; i<=n; ++i) 26 { 27 for(LL j=1; j<=m; ++j) 28 scanf("%lld",&val[i][j]); 29 } 30 memset(dp,INF,sizeof(dp)); 31 memset(pre,INF,sizeof(pre)); 32 for(int i=1; i<=m; ++i) 33 dp[1][i]=val[1][i]; 34 for(LL i=2; i<=n; ++i) 35 { 36 for(LL j=1; j<=m; ++j) 37 { 38 if(dp[i][j-1]<dp[i-1][j]) 39 { 40 pre[i][j]='L'; 41 dp[i][j]=dp[i][j-1]+val[i][j]; 42 } 43 else 44 { 45 pre[i][j]='D'; 46 dp[i][j]=dp[i-1][j]+val[i][j]; 47 } 48 } 49 for(LL j=m; j>=1; --j) 50 { 51 if(dp[i][j+1]+val[i][j]<dp[i][j]) 52 { 53 pre[i][j]='R'; 54 dp[i][j]=dp[i][j+1]+val[i][j]; 55 } 56 } 57 } 58 LL maxx=dp[n][1],pos=1,index=0; 59 for(LL i=2; i<=m; ++i) 60 { 61 if(maxx>dp[n][i]) 62 { 63 //printf("**%lld\n",i); 64 maxx=dp[n][i]; 65 pos=i; 66 } 67 } 68 v[index++]=pos; 69 //printf("%lld**\n",pos); 70 LL i=n,j=pos; 71 while(i!=1) 72 { 73 //printf("**\n"); 74 if(pre[i][j]=='D') 75 { 76 pos=j; 77 i--; 78 v[index++]=pos; 79 } 80 else if(pre[i][j]=='R') 81 { 82 j++; 83 pos=j; 84 v[index++]=pos; 85 } 86 else if(pre[i][j]=='L') 87 { 88 j--; 89 pos=j; 90 v[index++]=pos; 91 } 92 } 93 for(i=index-1; i>=0; --i) 94 { 95 //if(i==0) 96 printf("%lld\n",v[i]); 97 //else printf("%lld ",v[i]); 98 } 99 } 100 return 0; 101 }