题意:就是每行找出一个数,要求找的这些数连续,也就是8个方向,,也就是i,j只能往i+1,j+1...i+1,j....i+1,j-1走。。。
读懂题就很简单了,,数塔。。。。dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])+val[i][j]...记录路径就行,.不过要求要输出最右边,在这里被坑了1发。。。
代码有点挫。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll __int64
using namespace std;
const int MAXN=110;
const ll INF=10000000000000000ll;
ll dp[MAXN][MAXN],pre[MAXN][MAXN];
ll a[MAXN][MAXN];
int n,m;
void prin(ll u,int cur)
{
if(cur==0)
return;
if(pre[cur][u]!=-1)
prin(pre[cur][u],cur-1);
if(cur==n)
printf("%d",u);
else
printf("%d ",u);
}
int main()
{
int t,i,j,k,flag=1;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
scanf("%I64d",&a[i][j]);
dp[i][j]=INF;
}
}
for(i=1;i<=m;i++)
{
dp[0][i]=0;
}
memset(pre,-1,sizeof(pre));
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(j>1)
{
dp[i][j]=dp[i-1][j-1];
pre[i][j]=j-1;
}
if(dp[i][j]>=dp[i-1][j])
{
dp[i][j]=dp[i-1][j];
pre[i][j]=j;
}
if(j<m)
{
if(dp[i][j]>=dp[i-1][j+1])
{
dp[i][j]=dp[i-1][j+1];
pre[i][j]=j+1;
}
}
dp[i][j]+=a[i][j];
}
}
ll ans=INF;
ll temp;
for(i=1;i<=m;i++)
{
if(dp[n][i]<=ans)
{
ans=dp[n][i];
temp=i;
}
}
printf("Case %d\n",flag++);
prin(temp,n);
printf("\n");
}
}