题目描述:————————————————————————-
在这个题目中,每一列就是一个阶段,每个阶段都有3种决策:直行、右上和右下。
多阶段决策的最优化问题往往可以用动态规划解决,其中,状态及其转移
类似于回溯法中的解答树。解答树中的“层数”,也就是递归函数中的“当前填充位置”cur,描述的是即将完成的决策序号,在动态规划中被称为“阶段”。
#include<iostream>
#include<algorithm>
using namespace std;
#define maxm 10+10
#define maxn 100+10
#define INF 1000000
int m,n;
int a[maxm][maxn];
int d[maxm][maxn];
int nex[maxm][maxn];
void fun()
{
int ans=INF,row=0;
for(int j=n;j>=1;j--)
{
for(int i=1;i<=m;i++)
{
if(j==n)d[i][j]=a[i][j];
else
{
int rows[4]={0,i-1,i,i+1};
if(i==1)rows[1]=m;
if(i==m)rows[3]=1;
sort(rows,rows+4);
d[i][j]=INF;
for(int k=1;k<=3;k++)
{
if(a[i][j]+d[rows[k]][j+1]<d[i][j])
{
d[i][j]=a[i][j]+d[rows[k]][j+1];
nex[i][j]=rows[k];
}
}
//printf("nex(%d,%d) is %d\n",i,j,nex[i][j]);
}
if(j==1&&ans>d[i][j])
{ans=d[i][j];row=i;}
}
}
printf("%d",row);
for(int j=1,i=row;j<n;i=nex[i][j],j++)
printf(" %d",nex[i][j]);
printf("\n%d\n",ans);
}
int main()
{
while(scanf("%d",&m)!=EOF)
{
scanf("%d",&n);
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
fun();
}
// for(int i=1;i<=m;i++)
// for(int j=1;j<=n;j++)
// printf("%d",a[i][j]);
}