P6649 「SWTR-05」Grid
额么么,某年某市某区区赛搬运了这道题。
时隔一年,回来补题。
一眼动态规划。
考虑设
那么如何转移呢?
显然,进入第
考虑从刚进到第
后者可以预处理一个以
显然不行,这样此题复杂度就成
我们可以想到再维护一个以
于是此题复杂度
空间上可以滚动数组,不过没必要,总体量级也没变,注释里有。
寄 long long 的代码、、
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e3+84;
ll n,m,ans=0x7f7f7f7f,val[maxn][maxn],f[maxn][maxn],hzn[maxn],qzn[maxn];
int main(){
scanf("%lld%lld",&n,&m);
for(ll i=n;i>=1;i--)
for(ll j=1;j<=m;j++)
scanf("%lld",&val[i][j]);
for(ll i=1;i<=n;i++){
memset(hzn,0x7f,sizeof(hzn));
memset(qzn,0x7f,sizeof(qzn));
for(ll j=1;j<=m;j++)
qzn[j]=min(qzn[j-1],0ll)+val[i][j];
for(ll j=m;j>=1;j--)
hzn[j]=min(hzn[j+1],f[i-1][j])+val[i][j];
// hzn[j]=min(hzn[j+1],f[j])+val[i][j];滚动数组
for(ll j=1;j<=m;j++)
f[i][j]=min(hzn[j]+qzn[j]-val[i][j],hzn[j]);
// f[j]=min(hzn[j]+qzn[j]-val[i][j],hzn[j]);滚动数组
// printf("%lld %lld %lld %lld %lld Sherry\n",i,j,hzn[j],qzn[j],val[i][j]);
// }
}
for(ll i=1;i<=m;i++)
ans=min(ans,f[n][i]);
printf("%lld",ans);
return 0;
}