博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu3698 Let the light guide us(dp+线段树)
阅读量:7216 次
发布时间:2019-06-29

本文共 2984 字,大约阅读时间需要 9 分钟。

题意:在每行上选一个点,每个点都要各自对应的代价,同时相邻两行的点要满足 |j-k|≤f(i,j)+f(i+1,k)。问最小代价是多少。

 

题解:

不难发现这是一道dp,状态转移方程如下$dp[i][j]=min\{dp[i-1][k]\}+t[i][j](|j-k|≤f(i,j)+f(i+1,k))$

然而如果直接进行转移是要T飞的

所以如何快速求$k$呢?

可以发现,$dp[i-1][k]$只会对一个区间的答案产生影响,而$dp[i][j]$的答案必定是一个区间中的最小值加上自己的时间

于是就是区间修改和区间查询了,之间上线段树

ps:因为$dp$数组每一行都会更新,实际上可以省掉第一维的空间

1 //minamoto 2 #include
3 #include
4 using namespace std; 5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 6 char buf[1<<21],*p1=buf,*p2=buf; 7 template
inline bool cmin(T&a,const T&b){
return a>b?a=b,1:0;} 8 inline int read(){ 9 #define num ch-'0'10 char ch;bool flag=0;int res;11 while(!isdigit(ch=getc()))12 (ch=='-')&&(flag=true);13 for(res=num;isdigit(ch=getc());res=res*10+num);14 (flag)&&(res=-res);15 #undef num16 return res;17 }18 char sr[1<<21],z[20];int C=-1,Z;19 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}20 inline void print(int x){21 if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;22 while(z[++Z]=x%10+48,x/=10);23 while(sr[++C]=z[Z],--Z);sr[++C]='\n';24 }25 const int N=105,M=5005,inf=0x3f3f3f3f;26 int t[N][M],f[N][M],dp[M],sum[M<<2],add[M<<2];27 int n,m;28 void pushdown(int p){29 if(add[p]!=inf){30 cmin(add[p<<1],add[p]),cmin(add[p<<1|1],add[p]);31 cmin(sum[p<<1],add[p<<1]),cmin(sum[p<<1|1],add[p<<1|1]);32 add[p]=inf;33 }34 }35 void build(int l,int r,int p){36 sum[p]=add[p]=inf;37 if(l==r) return;38 int mid=l+r>>1;39 build(l,mid,p<<1),build(mid+1,r,p<<1|1);40 }41 void update(int ql,int qr,int x,int l,int r,int p){42 if(ql<=l&&qr>=r){43 cmin(add[p],x),cmin(sum[p],add[p]);return;44 }45 int mid=l+r>>1;46 pushdown(p);47 if(ql<=mid) update(ql,qr,x,l,mid,p<<1);48 if(qr>mid) update(ql,qr,x,mid+1,r,p<<1|1);49 sum[p]=min(sum[p<<1],sum[p<<1|1]);50 }51 int query(int ql,int qr,int l,int r,int p){52 if(ql<=l&&qr>=r) return sum[p];53 int mid=l+r>>1;54 pushdown(p);55 int res=inf;56 if(ql<=mid) cmin(res,query(ql,qr,l,mid,p<<1));57 if(qr>mid) cmin(res,query(ql,qr,mid+1,r,p<<1|1));58 return res;59 }60 int main(){61 //freopen("testdata.in","r",stdin);62 while(true){63 n=read(),m=read();64 if(n==0&&m==0) break;65 for(int i=1;i<=n;++i)66 for(int j=1;j<=m;++j)67 t[i][j]=read();68 for(int i=1;i<=n;++i)69 for(int j=1;j<=m;++j)70 f[i][j]=read();71 for(int i=1;i<=m;++i) dp[i]=t[1][i];72 for(int i=2;i<=n;++i){73 build(1,m,1);74 for(int j=1;j<=m;++j)75 update(j-f[i-1][j],j+f[i-1][j],dp[j],1,m,1);76 for(int j=1;j<=m;++j)77 dp[j]=query(j-f[i][j],j+f[i][j],1,m,1)+t[i][j];78 }79 int ans=inf;80 for(int i=1;i<=m;++i) cmin(ans,dp[i]);81 print(ans);82 }83 Ot();84 return 0;85 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9462694.html

你可能感兴趣的文章
FlasCC发布说明
查看>>
如何在macOS Sierra中运行CORE Keygen破解程序
查看>>
终极解决方案:windows10资源管理器假死
查看>>
【java】一维数组循环位移方阵
查看>>
Essential Studio for mobile MVC中创建Razor应用程序平台教程
查看>>
java主函数的含义
查看>>
中国大学MOOC —— 学习笔记(四)
查看>>
访问,ringbtn,
查看>>
致橡树
查看>>
一段测试代码,哦哦哦,
查看>>
uiimagepickercontroller,中文,--》摘
查看>>
第四次作业
查看>>
在python中调用js或者nodejs
查看>>
【年终总结】2年计划还是要有的,万一实现了呢?(转自叶小钗)
查看>>
数字图像处理学习笔记(1.1)---位图的读写、几何变换、傅里叶变换、直方图均衡...
查看>>
javascript数组顺序-----1冒泡的另一种比较好理解的写法
查看>>
数据结构-栈的实现之行编译器核心实现
查看>>
C++ Project 积累(2)
查看>>
(1)用VisualSvn Server,Tortoise Svn,AnkhSvn搭建Svn版本控制
查看>>
Mysql索引
查看>>