-
D - Jumping Haybales
- Gym - 101617D
- 题意:
- 从1,1到n, n求最小步数只是每一秒可以向右或向下走k步若是直接搜索无疑会超时
- 即便是dp也会超时 只有维护k步内最小值直接进行优化即可,
- 维护方法有多重选择了简单点的线段树
- 注意线段树的=的位置,Otherwise, it will RE....
- 不过线段树也在TLE MLE的边缘
-
#include<bits/stdc++.h> using namespace std; #define maxn 2111 #define inf 0x3f3f3f3f #define ll int ll n,tx,ty; int k; char mmp[maxn][maxn]; struct node { ll l,r,num; } L[maxn][maxn*4],R[maxn][maxn*4]; ll dp[maxn][maxn]; void creat(node *tree,ll l,ll r,ll root) { tree[root].l=l; tree[root].r=r; if(l==r) { tree[root].num=inf; return ; } ll mid=(l+r)/2; creat(tree,mid+1,r,root*2+1); creat(tree,l,mid,root*2); tree[root].num=min(tree[root*2].num,tree[root*2+1].num); } void updata(node *tree,ll l,ll ad,ll root) { if(tree[root].l==l&&tree[root].r==l) { tree[root].num=ad; return ; } ll mid=(tree[root].l+tree[root].r)/2; if(l<=mid) updata(tree,l,ad,root*2); else updata(tree,l,ad,root*2+1); tree[root].num=min(tree[root*2].num,tree[root*2+1].num); } ll query(node *tree,ll l,ll r,ll root) { if(tree[root].l==l&&tree[root].r==r) return tree[root].num; ll mid=(tree[root].l+tree[root].r)/2; if(l>mid) return query(tree,l,r,root*2+1); else if(mid>=r) return query(tree,l,r,root*2); else return min(query(tree,l,mid,root*2),query(tree,mid+1,r,root*2+1)); } int main() { ios::sync_with_stdio(false); cin>>n>>k; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { cin>>mmp[i][j]; dp[i][j]=inf; } dp[1][1]=0; for(int i=1; i<=n; i++) { creat(L[i],1,n,1); creat(R[i],1,n,1); } updata(L[1],1,0,1); updata(R[1],1,0,1); for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { if(i==1&&j==1) continue; if(mmp[i][j]=='#')continue; dp[i][j]=min(dp[i][j],min(query(L[i],max(1,j-k),j,1),query(R[j],max(1,i-k),i,1))+1); if(dp[i][j]!=inf) { updata(L[i],j,dp[i][j],1); updata(R[j],i,dp[i][j],1); } } if(dp[n][n]==inf) cout<<-1<<endl; else cout<<dp[n][n]<<endl; return 0; }
D - Jumping Haybales -线段优化坐标DP
最新推荐文章于 2018-12-18 17:14:38 发布