题意:给定一个n*m的矩阵,从第一列任意位置向右,右下,右上走一格,可以循环,要求经过的数字的和最小。
思路:记忆化搜索。每次有三个状态,从这三个状态中选择出最优的一个,然后状态累加,保存路径。
code:
#include <bits/stdc++.h>
using namespace std;const int N=11;
const int M=105;
#define ft(i,s,t) for (int i=s;i<=t;i++)
#define frt(i,t,s) for (int i=t;i>=s;i--)
int g[N][M],s[N][M];int main()
{int n,m,t,tt;while (~scanf("%d %d",&n,&m)){ft(i,0,n-1) ft(j,0,m-1) scanf("%d",&g[i][j]);frt(j,m-2,0) ft(i,0,n-1){int bt=(i+n-1)%n;if (g[i][j+1]<g[bt][j+1]||g[i][j+1]==g[bt][j+1]&&bt>i) bt=i; //右上和直走的最优解int t=(i+1)%n;if (g[t][j+1]<g[bt][j+1]||g[t][j+1]==g[bt][j+1]&&bt>t) bt=t;//右下和全部g[i][j]+=g[bt][j+1];s[i][j]=bt; //状态记忆和保存路径}int p=n-1;frt(i,n-2,0) if (g[p][0]>=g[i][0]) p=i;int ans=g[p][0];ft(i,0,m-2){printf("%d ",p+1);p=s[p][i];}printf("%d\n%d\n",p+1,ans);}
}