HDU 3698-Let the light guide us(线段树+DP)愿圣光忽悠你
来源:互联网 发布:java 图片文字合成 编辑:程序博客网 时间:2024/05/21 10:56
题意:
给定两个矩阵,第一个矩阵代表时间,第二个矩阵代表距离。给出约束的公式,询问在每一行都造一个圣光塔最少花费多少时间!
思路:
对于题目中给的条件 |J-K| <=f[i][j] +f[i+1] [k] 若拆掉绝对值可以得到 K+f[i+1][k] >= j- f[i] [j] k-f[i+1][k] <= j+f[i][j]
若M很小的话 ,我们自然可以通过一个很好看出来的 DP来AC 。DP的方程为:
dp[i ][ j] = min( dp[i ] [j] , dp[i-1] [k ] + timed[ i] [j] ) ,但是如果我们暴力枚举的话是m*m *n 的复杂度,显然会TLE
再重新考虑不等式约束,可以发现K的范围只是在 j-f[i][j] ,f+ f[i][j]之间 ,也就是我们每次DP转移方程 是在这个范围内取得最小值。
对于这个问题显然线段树就可以搞定!维护区间最小值
#include<algorithm>#include<iostream>#include<sstream>#include<string.h>#include<stdio.h>#include<math.h>#include<vector>#include<string>#include<queue>#include<map>using namespace std;const int inf=0x3f3f3f3f;int n,m,ans;const int maxn=5005;int timed[105][maxn];int dp[105];int f[105][maxn];struct node{ int left,right; int minn,val;}tree[maxn*4];void build(int i,int left,int right){ tree[i].left=left,tree[i].right=right; tree[i].minn=inf,tree[i].val=inf ; if(left==right) return; int mid=(left+right)>>1; build(i<<1,left,mid); build(i<<1|1,mid+1,right); return ;}void pushdown(int i){ int mid=tree[i].left+tree[i].right; mid=mid>>1; tree[i<<1].val= min(tree[i<<1].val,tree[i].val); tree[i<<1|1].val=min(tree[i<<1|1].val,tree[i].val); tree[i<<1].minn= min(tree[i<<1].minn,tree[i].val); tree[i<<1|1].minn=min(tree[i<<1|1].minn,tree[i].val); tree[i].val=inf;}void update(int i,int left,int right,int w){ if(tree[i].left==left&&tree[i].right==right) { tree[i].val=min(tree[i].val,w); tree[i].minn=min(tree[i].minn,w); return ; } if(tree[i].val!=inf) { pushdown(i); } int mid=(tree[i].left+tree[i].right)>>1; if(right<=mid) update(i<<1,left,right,w); else if(left>mid) update(i<<1|1,left,right,w); else { update(i<<1,left,mid,w); update(i<<1|1,mid+1,right,w); } tree[i].minn=min(tree[i<<1].minn,tree[i<<1|1].minn); return ;}void query(int i,int left,int right){ if(tree[i].left==left&&tree[i].right==right) { ans=min(ans,tree[i].minn); return ; } int mid=(tree[i].left+tree[i].right)>>1; if(tree[i].val!=inf) { pushdown(i); } if(right<=mid) query(i<<1,left,right); else if(left>mid) query(i<<1|1,left,right); else { query(i<<1,left,mid); query(i<<1|1,mid+1,right); } tree[i].minn=min(tree[i<<1].minn,tree[i<<1|1].minn); return ;}int main(){ while(~scanf("%d%d",&n,&m)&&(n+m)) { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf("%d",&timed[i][j]); } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf("%d",&f[i][j]); } } for(int i=1;i<=m;i++) { dp[i]=timed[1][i]; } for(int i=2;i<=n;i++) { build(1,1,m); for(int j=1;j<=m;j++) { int l=max(j-f[i-1][j],1); int r=min(j+f[i-1][j],m); update(1,l,r,dp[ j ]); } for(int j=1;j<=m;j++) { int l=max(j-f[i][j],1); int r=min(j+f[i][j],m); ans=inf; query(1,l,r); dp[j]=ans+timed[i][j]; } // for(int i=1;i<=m;i++) // printf("%d ",dp[i]); // printf("\n"); } int minnn=inf; for(int i=1;i<=m;i++) { minnn=min(minnn,dp[i]); } printf("%d\n",minnn); }}
0 0
- HDU 3698-Let the light guide us(线段树+DP)愿圣光忽悠你
- 【HDU】3698 Let the light guide us 线段树+DP
- HDU-3689 Let the light guide us 线段树+DP
- hdu 3698 Let the light guide us【线段树+dp】 2010 Asia Fuzhou Regional Contest
- HDU 3698 Let the light guide us 线段树求区间优化dp
- HDU 3698 Let the light guide us (DP+线段树) #by Plato
- dp+线段树优化-hdu-3698-Let the light guide us
- hdu 3698 Let the light guide us(线段树优化&简单DP)
- HDU 3698 Let the light guide us dp+线段树维护区间极值
- 【DP+线段树】 hdu3698 Let the light guide us
- Let the light guide us HDU
- hdu3698 Let the light guide us
- LA5106: Let the light guide us
- hdu3698——Let the light guide us
- dp+segtree _ fz2010_Let the light guide us
- hdu 4276 The Ghost Blows Light(树型DP)
- hdu 4276 The Ghost Blows Light(树型DP)
- HDU - 4276 The Ghost Blows Light(spfa + 树上dp)
- 高效开发使用框架请求https(xutils3 Nohttp,OkhttpUtils(zhy))
- 泛型
- JAVA 对象存放的位置
- BZOJ2194: 快速傅立叶之二
- 解决文字和text-decoration:underline下划线重叠问题
- HDU 3698-Let the light guide us(线段树+DP)愿圣光忽悠你
- 线性结构中的插入删除基本运算
- Android 身份证号有效性校验工具类
- nginx.conf配置文件解析(http、server、location)
- ZOJ 2760 How Many Shortest Path(最短路径计数)
- TCP/UDP
- anglular-动态购物车-watch-index
- JavaScript---正则表达式问题
- 顺序访问和随机访问