昨天到刚才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; }