我觉得这题的难度恶评了啊。。。
感觉明明不止普及—的难度啊还是我DP太菜了
设f[i][j]表示到了第i组第j个步骤时能用的最短时间
答案是把f[1~m][n]中找一个最小值
初值全为0x3f3f3f3f,然后每组第1个步骤就等于该步骤所用的时间
方程:(特判i=1的情况)一种情况是从原来这队继续走,另一种是从i-1队变过来
if(i!=1){
f[i][j]=min(f[i][j],f[i][j-1]+a[i][j]);
f[i][j]=min(f[i][j],f[i-1][j-1]+a[i][j]);
}
if(i==1){
f[i][j]=min(f[i][j],f[i][j-1]+a[i][j]);
f[i][j]=min(f[i][j],f[m][j-1]+a[i][j]);
}
然后注意枚举i的时候应该是m~1(因为如果顺序,推f[1][]的时候f[m][]的值还没出来)
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int a[2007][2007];
int f[2007][2007];
int ans;
int n,m;
int main(){
memset(f,0x3f,sizeof(f));
memset(a,0x3f,sizeof(a));
cin>>n>>m;
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++){
cin>>a[i][j];
if(j==1)f[i][j]=a[i][j];
}
for(int j=1;j<=n;j++)
for(int i=m;i>=1;i--){
if(i!=1){
f[i][j]=min(f[i][j],f[i][j-1]+a[i][j]);
f[i][j]=min(f[i][j],f[i-1][j-1]+a[i][j]);
}
if(i==1){
f[i][j]=min(f[i][j],f[i][j-1]+a[i][j]);
f[i][j]=min(f[i][j],f[m][j-1]+a[i][j]);
}
}
int ans=0x3f3f3f3f;
for(int i=1;i<=m;i++)
ans=min(ans,f[i][n]);
cout<<ans<<endl;
return 0;
}