昨天到刚才CSDN一直有点抽..发不了日志..长假过后的第一题...这道题主要就是题目难的看懂...我也是后来找了翻译才看懂的...
明白了意思后就很好做了...开始写的是二维的滚动..就是从第一层一直做到顶层..每次先将当前位置下一层的相同位置更新上来..然后左扫更新一遍...再右扫更新一遍...稍微一想能发现..这厮其实用一维的就可以了...先前每次到了新的一层就先把下一层的先更新上来再扫两次..这个其实就直接在一个数组里给自加一下当前位置的价值就ok了...
再一个地方就是输出的是路径..有点eggache...开始我很傻×的在DP时用个结构体在更新时跟着传递...交上去不是超时就是爆空间..我AC用的方法就是用一个 Link [ h ] [ k ] 来记录第h层第k个官员的上一个是什么位置..Link是个有y,x两个元素的结构体...这样做完后再走一遍...路径就出来了..
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int m,n,a[501],i,j,k,dp[501],way[101*501],l,p;
struct pp
{
int x,y;
}link[101][501];
int main()
{
while(~scanf("%d%d",&m,&n))
{
memset(dp,0,sizeof(dp));
memset(link,0,sizeof(link));
for (p=1;p<=m;p++)
{
for (i=1;i<=n;i++) scanf("%d",&a[i]);
for (i=1;i<=n;i++)
{
dp[i]+=a[i];
link[p][i].y=p-1;
link[p][i].x=i;
}
for (i=2;i<=n;i++)
if (dp[i]>dp[i-1]+a[i])
{
dp[i]=dp[i-1]+a[i];
link[p][i].y=p;
link[p][i].x=i-1;
}
for (i=n-1;i>=1;i--)
if (dp[i]>dp[i+1]+a[i])
{
dp[i]=dp[i+1]+a[i];
link[p][i].y=p;
link[p][i].x=i+1;
}
}
int x=1,y=m,tx,ty;
for (i=2;i<=n;i++) x=dp[x]<dp[i]?x:i;
l=0;
while (y)
{
l++;
way[l]=x;
ty=y; tx=x;
y=link[ty][tx].y;
x=link[ty][tx].x;
}
for (i=l;i>=1;i--)
printf("%d ",way[i]);
printf("\n");
}
return 0;
}