LA5106: Let the light guide us
Dp·树状数组
题解:
裸方程:
当|j−k|<=magic[i−1][k]+magic[i][j]时,
f[i][j]=min{f[i−1][k]}+cost[i][j]
时间复杂度:O(nm2).
优化一下。像这种有绝对值的一定是规定大小,把绝对值去掉,然后正反做两遍。
k<=j,k−magic[i−1][k]<=j+magic[i][j]
然后用bit维护最小值即可。详见代码。
时间复杂度:O(nmlogm).
说一下我犯的zz错误:
1.先正着跑完所有行在反着跑所有行。。。
2.reverse没写足,有的没reverse回来。。。
Code:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
//#define debug
#ifdef debug
#define D(x) cout<<#x<<" = "<<x<<" "
#define E cout<<endl
#else
#define D(x)
#define E
#endif
using namespace std;
const int N = 5005;
const int mxn = 200000;
const int INF = 0x3f3f3f3f;
int n,m,cost[105][N],magic[105][N],f[N],g[N],res[N],ans;
struct BIT{
int c[mxn+5], sz;
void init(int _sz){ sz=_sz; memset(c,0x3f,sizeof(c)); }
void ins(int x,int d){ if(x<1)x=1; while(x<=sz){ c[x]=min(c[x],d); x+=x&(-x); } }
void clear(int x){ if(x<1)x=1; while(x<=sz){ c[x]=INF; x+=x&(-x); } }
int mn(int x){ int ans=INF; while(x>0){ ans=min(ans,c[x]); x-=x&(-x); } return ans; }
} bit;
void dp(int i,int f[N]){
// printf("dp: \n");
for(int j=m;j>=1;j--){
D(i); D(j); E;
// printf("ins: pos=%d d=%d\n",j-magic[i-1][j],res[j]);
bit.ins(j-magic[i-1][j],res[j]);
D(j+magic[i][j]); D(bit.mn(j+magic[i][j])); E;
f[j]=bit.mn(j+magic[i][j])+cost[i][j];
D(f[j]); E;
}
for(int j=1;j<=m;j++) bit.clear(j-magic[i-1][j]);
}
int main(){
freopen("a.in","r",stdin);
#ifndef debug
freopen("a.out","w",stdout);
#endif
while(scanf("%d%d",&n,&m), n||m){
D(n); D(m); E;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) scanf("%d",&cost[i][j]);
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) scanf("%d",&magic[i][j]);
bit.init(mxn); for(int i=1;i<=m;i++)res[i]=cost[1][i];
for(int i=2;i<=n;i++){
memset(f,0x3f,sizeof(f)); memset(g,0x3f,sizeof(g));
dp(i,f);
reverse(cost[i]+1,cost[i]+1+m);
reverse(magic[i]+1,magic[i]+1+m);
reverse(magic[i-1]+1,magic[i-1]+1+m);
reverse(res+1,res+1+m);
dp(i,g);
reverse(magic[i]+1,magic[i]+1+m);
reverse(res+1,res+1+m);
for(int j=1;j<=m;j++)res[j]=min(f[j],g[m-j+1]);
}
ans=INF; for(int j=1;j<=m;j++) ans=min(ans,res[j]);
printf("%d\n",ans);
}
}