分层dp:天堂(heaven)

题目描述每一个要上天堂的人都要经历一番考验,当然包括小X,小X开始了他进入天堂的奇异之旅。地狱有18层,天堂竟然和地狱一样,也有很多很多层,天堂共有N层。从下到上依次是第1,2,3,…,N层,天堂的每一层都是一个延伸无限远的地板,在地板上人可以任意走动,层与层之间是平行关系,每一层的地板都是由人不能穿过的物质构成,幸好每一层地板上有且仅有1个人可以通过的洞口。我们可以把小X和洞口,还有下面提到的气球店都看成点,坐标是二维的。小X开始在第31层的(0,0).小X的重量为M,第i层与第i+1层之间的特殊气体能浮起的重量为Wi ,每一层的地面上散落了若干个气球店,多个气球店可以在同一点,每个气球可以浮起的重量是1,去一个气球店一次只能领取一个气球,不能连续在一个气球店领取气球,当然你可以在两个气球店之间来回跑,每个气球店供应的气球都是无限多的。第i层的气球只能在第i层进入第i+1层时使用,当小X在第i层,只有站到了第i+1层洞口的位置(在其它位置不会浮起),并且自身的重量小于等于气球和特殊气体浮起重量的总和,才可以进入第i+1层。小X想知道他要到达第N层走过的长度最少是多少?题目保证有解。输入文件第1行: 三个正整数N,M,Q(Q表示气球店)第2行: 共2*(N-1)个整数,每两个数描述1个洞口坐标,第i对xi,yi表示第i+1层的洞口位置(xi,yi)。第3行: 共N-1个整数,第i个数为Wi。往后Q行,每行三个整数x,y,z , 表示第Z层有一个气球店,坐标为(x,y)输出文件1个实数L,保留两位小数,表示小X最少要走的长度。样例输入3 10 40 0 1 29 00 1 12 3 10 1 21 1 2样例输出13.00注释【样例解释】在第一层从(0,0)出发到(0,1)取得1个气球并返回(0,0)即可到达第二层。长度:2.00在第二层,从(0,0)到(0,1)领取气球,再到(1,1)领取气球,两个点来回跑,第5次到达(1,1)时恰好气球数达到10,走到(1,2)即可到达第3层终点。长度:11.00总长度:13.00【数据范围】2<=N<=100每层的气球店数目不超过50。0<=M<=100, 0<=Wi<=100坐标-3000<=x,y<=3000

可以看出,每一层与其它层是互不影响的。对于第x层,共有number[x]个气球店,气体浮力为air[x],即需领m-air[x]个气球f[i,j]表示在第i个气球点领取第j个气球f[i,j]:=min(f[k,j-1]+dist[i,j])    {i<>k}f[i,1]:=起点到每一个气球店的距离第x层最小的移动距离为min{f[i,m-air[x]]+终点到i的距离}

and 不能再把数据范围看错了

code:
var n,m,q:longint;    pole:array[1..200]of record                        x,y:longint;                        end;    air:array[1..200]of longint;    number:array[1..200]of longint;    position:array[1..200,1..60]of record                            x,y:longint;                            end;    f:array[1..1010,1..1000]of double;    dist1,dist2:array[1..100]of double;    dist:array[1..100,1..100]of double;    ii,i,j,k:longint;    sx,sy,fx,fy:longint;    x,y,z:longint;    min,ans:double;    temp:double;
begin       readln(n,m,q);      for i:=2 to n do          read(pole[i].x,pole[i].y);      for i:=1 to n-1 do          read(air[i]);      fillchar(position,sizeof(position),0);      fillchar(number,sizeof(number),0);      for i:=1 to q do          begin readln(x,y,z);                inc(number[z]);                position[z,number[z]].x:=x;                position[z,number[z]].y:=y;          end;      ans:=0;      sx:=pole[1].x;      sy:=pole[1].y;      for ii:=1 to n-1 do          begin if air[ii]<m                   then begin fillchar(dist1,sizeof(dist1),0);                              fillchar(dist2,sizeof(dist2),0);                              fillchar(dist,sizeof(dist),0);                              for i:=1 to number[ii] do                                  dist1[i]:=sqrt(sqr(position[ii,i].x-sx)+                                                 sqr(position[ii,i].y-sy));                              for i:=1 to number[ii] do                                  for j:=1 to number[ii] do                                      dist[i,j]:=sqrt(sqr(position[ii,i].x-position[ii,j].x)+                                                      sqr(position[ii,i].y-position[ii,j].y));                              for i:=1 to number[ii] do                                  for j:=1 to m-air[ii] do                                      f[i,j]:=maxint*5000;                              for i:=1 to number[ii] do                                  f[i,1]:=dist1[i];                              fx:=pole[ii+1].x;                              fy:=pole[ii+1].y;                              for i:=1 to number[ii] do                                  dist2[i]:=sqrt(sqr(position[ii,i].x-fx)+                                                 sqr(position[ii,i].y-fy));                              for j:=2 to m-air[ii] do                                  for i:=1 to number[ii] do                                      for k:=1 to number[ii] do                                          if (f[i,j]>f[k,j-1]+dist[i,k])and(i<>k)                                             then f[i,j]:=f[k,j-1]+dist[i,k];                              min:=maxlongint;                              for i:=1 to number[ii] do                                  if min>f[i,m-air[ii]]+dist2[i]                                     then min:=f[i,m-air[ii]]+dist2[i];                              ans:=ans+min;                              sx:=pole[ii+1].x;                              sy:=pole[ii+1].y;                        end                   else begin fx:=pole[ii+1].x;                              fy:=pole[ii+1].y;                              ans:=ans+sqrt(sqr(sx-fx)+sqr(sy-fy));                              sx:=pole[ii+1].x;                              sy:=pole[ii+1].y;                        end;          end;      writeln(ans:0:2);

end.
时间: 2024-08-04 14:23:53

分层dp:天堂(heaven)的相关文章

bzoj1190--梦幻岛宝珠--分层dp+01背包(未完成)

Description 给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值.数据范围:N<=100;W<=2^30,并且保证每颗宝石的重量符合a*2^b(a<=10;b<=30) Input 输入文件中包含多组数据.每组数据的格式如下:第一行是两个正整数n和W,1≤n≤100,1≤W≤2^30,分别表示宝石的数目和最多能带走的宝石重量.接下来的n行,每行有两个正整数weighti和valuei,1≤weight

bzoj2244[SDOI2011]拦截导弹

http://www.lydsy.com/JudgeOnline/problem.php?id=2244 第$i$个导弹看成一个三元组$(i,h_i,v_i)$ 其实就是最长上升子序列的问题. 我们分别求以第$i$个导弹为结尾的最长上升子序列的长度和个数,以及以第$i$个导弹为开头的最长上升子序列的长度和个数. 下面以求以第$i$个导弹为结尾的最长上升子序列的长度和个数为例. 记以第$i$个导弹结尾的最长上升子序列长度为$f[i]$,则: $$f[i]=Max\{f[j]|j<i,h[j]\ge

NOIP前刷水行动

2016.11.10 BZOJ1592 Usaco2008 Feb]Making the Grade 路面修整:离散+DP BZOJ1051 HAOI 受欢迎的牛 :tarjan BZOJ2442 修建草坪 :单调队列优化DP BZOJ3890 Meeting time : 分层DP BZOJ4390 Max Flow :树上差分 BZOJ4525 :二分答案判定 BZOJ4511 :DP 1 BZOJ1592 2 3 #include<iostream> 4 #include<algo

省队集训 Day3 陈姚班

[题目大意] 给一张网格图,上往下有流量限制,下往上没有,左往右有流量限制. $n * m \leq 2.5 * 10^6$ [题解] 考场直接上最大流,50分.竟然傻逼没看出狼抓兔子. 平面图转对偶图,其中没有流量限制(inf)不用转,然后直接在DAG上分层dp即可. 复杂度$O(nm)$,但是这样过不去被卡常了. 出题人的做法是先处理出每层初始的那个随机数,然后每层往下直接做,这样因为是一维数组,所以寻址方便,不会被卡常. 我的做法是动态开数组(用new),然后比较两维大小来分配第一维给谁,

BZOJ 2244 SDOI2011 拦截导弹 CDQ分治/二维树状数组

题目大意:给定一个序列,每个元素是一个二元组,等概率选择一LIS,求LIS长度以及每个元素被选中的概率 第一问CDQ分治裸上 第二问用每个元素所在的LIS个数/总LIS个数就是答案 每个元素所在的LIS自己必选,然后统计前面的方案数和后面的方案数 以前面的方案数为例,令f[x]为以x结尾的LIS长度,那么有DP方程: g[i]=Σg[j] (f[j]+1=f[i],j<i,a[j].x<a[i].x,a[j].y<a[i].y) 将所有元素按f值排序,分层DP,每层DP是一个三维偏序,上

【noi 2.6_9289】&amp;【bzoj2023 / 1630】Ant Counting 数蚂蚁{Usaco2005 Nov}

题意:有M个家族的蚂蚁,各Ni只(互相相同).问选出 l~r 只的不同组合数. 解法:很基础的一种DP,不要被“排列组合”所迷惑了啊~我之前接触过这个类型,可惜又忘了,一定要记住!这是一种类型的DP——M种N个进行DP,定义f[i][j]表示前 i 种中(这题是“家族”)选了 j 个(“只”蚂蚁)的方案数.再进行分层DP. 所以f[i][j]=sum{f[i-1][j-k]} (0<=k<=Ni),再利用前缀和优化时间+滚动数组优化空间就可以了. 1 #include<cstdio>

CodeForces 868F Yet Another Minimization Problem(决策单调性优化 + 分治)

题意 给定一个序列 \(\{a_1, a_2, \cdots, a_n\}\),要把它分成恰好 \(k\) 个连续子序列. 每个连续子序列的费用是其中相同元素的对数,求所有划分中的费用之和的最小值. \(2 \le n \le 10^5, 2 \le k \le \min(n, 20), 1 \le a_i \le n\) 题解 \(k\) 比较小,可以先考虑一个暴力 \(dp\) . 令 \(dp_{k, i}\) 为前 \(i\) 个数划分成 \(k\) 段所需要的最小花费. 那么转移如下

【bzoj1190】[HNOI2007]梦幻岛宝珠 分层背包dp

题目描述 给你N颗宝石,每颗宝石都有重量和价值.要你从这些宝石中选取一些宝石,保证总重量不超过W,且总价值最大为,并输出最大的总价值.数据范围:N<=100;W<=2^30,并且保证每颗宝石的重量符合a*2^b(a<=10;b<=30) 输入 输入文件中包含多组数据.每组数据的格式如下:第一行是两个正整数n和W,1≤n≤100,1≤W≤2^30,分别表示宝石的数目和最多能带走的宝石重量.接下来的n行,每行有两个正整数weighti和valuei,1≤weighti≤2^30, 0≤

分层图最短路(DP思想) BZOJ2662 [BeiJing wc2012]冻结

2662: [BeiJing wc2012]冻结 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 999  Solved: 535[Submit][Status][Discuss] Description "我要成为魔法少女!" "那么,以灵魂为代价,你希望得到什么?" "我要将有关魔法和奇迹的一切,封印于卡片之中??" 在这个愿望被实现以后的世界里,人们享受着魔法卡片(SpellCard,又名符 卡