天堂(heaven)

题目描述

每一个要上天堂的人都要经历一番考验,当然包括小X,小X开始了他进入天堂的奇异之旅。地狱有18层,天堂竟然和地狱一样,也有很多很多层,天堂共有N层。从下到上依次是第1,2,3,…,N层,天堂的每一层都是一个延伸无限远的地板,在地板上人可以任意走动,层与层之间是平行关系,每一层的地板都是由人不能穿过的物质构成,幸好每一层地板上有且仅有1个人可以通过的洞口。

我们可以把小X和洞口,还有下面提到的气球店都看成点,坐标是二维的。小X开始在第1层的(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 4

0 0 1 2

9 0

0 1 1

2 3 1

0 1 2

1 1 2

样例输出

13.00

【数据范围】

2<=N<=100

每层的气球店数目不超过50。

0<=M<=100,   0<=Wi<=100

坐标-3000<=x,y<=3000

一开始看上去以为和图论有关,没有意识到是DP,用了搜索,居然还得了30分。但是这题每层的气球只在每一层用,只要想到了用DP,以每一层为单位,分别求出最优解。方程就很好想了,转移方程也不是难点。重点在思维,思维没到什么都是白搭。不多说上代码!

  1. /*
  2. ID: ringxu97
  3. LANG: C++
  4. TASK: heaven
  5. SOLUTION:动态规划
  6. */
  7. #include<cstdio>
  8. #include<cstring>
  9. #include<iostream>
  10. #include<cmath>
  11. #include<cstdlib>
  12. #include<algorithm>
  13. #include<vector>
  14. using namespace std;
  15. const int MAXM=+,MAXN=+,MAXW=+,MAXQ=+;
  16. const double maxlen=0x7fffffff;//用极大值定义最远的距离
  17. const double err=1e-;
  18. double opt[MAXM][MAXQ];//储存动归状态
  19. //opt[i][j]表示在一层中最买已经买到到i个气体并且在第j个商店时走的最少距离
  20. //状态转移方程为opt[i][j]=min{opt[i-1][k]+distance(k,j) | k!=j}
  21. struct point//定义点的结构体
  22. {
  23. int x,y;//所有点都是整数点
  24. point(){x=y=;}
  25. point(int i,int j){x=i;y=j;}
  26. double dist(point a)//成员函数,用于计算距离
  27. {
  28. return (double)sqrt( (a.x-x)*(a.x-x) + (a.y-y)*(a.y-y));//直接带入公式计算
  29. }
  30. };
  31. vector<point>shop[MAXN];//使用邻接链表储存每一层的商店,节约空间并给商店编号,方便状态转移
  32. point hole[MAXN];//每一层洞口的位置
  33. int W[MAXN];//气体的浮力
  34. int N,M,Q;
  35.  
  36. void readdata()//数据的读入,注意邻接链表的处理
  37. {
  38. scanf("%d%d%d",&N,&M,&Q);
  39. for(int i=;i<N;++i)scanf("%d%d",&hole[i].x,&hole[i].y);
  40. for(int i=;i<N;++i)scanf("%d",W+i);
  41. for(int i=;i<=Q;++i)
  42. {
  43. int x,y,z;
  44. scanf("%d%d%d",&x,&y,&z);
  45. point tmp(x,y);
  46. shop[z].push_back(tmp);
  47. }
  48. }
  49. int main()
  50. {
  51. freopen("heaven.in", "r", stdin);
  52. freopen("heaven.out", "w", stdout);
  53. readdata();
  54. point pos(,);//pos储存当前所在的位置,初始在(0,0)
  55. double d=;//记录已经走过的距离
  56. for(int f=;f<N;++f)//循环计算每一层楼的情况
  57. {
  58. int buy=M-W[f]>?M-W[f]:;//需要购买的气球数量,注意如果浮力大于体重则不需要购买,即购买数量为0
  59. double best=maxlen;//动归过程中储存最优值的变量,初始为无穷大
  60. if(buy)
  61. {
  62. memset(opt,,sizeof(opt));//每一层动归前,初始化数组
  63. int border=shop[f].size();//邻接表的边界
  64. for(int i=;i<border;++i)
  65. opt[][i]=pos.dist(shop[f][i]);//给初始状态赋值
  66. for(int i=;i<=buy;++i)//以下为动归过程
  67. for(int j=;j<border;++j)
  68. {
  69. opt[i][j]=maxlen;
  70. for(int k=;k<border;++k)if(k!=j)//题目中已经规定k不能与j相同
  71. opt[i][j]=min(opt[i-][k]+shop[f][j].dist(shop[f][k]),opt[i][j]);
  72. }
  73. for(int i=;i<border;++i)//动归完成后计算最优方案的值
  74. best=min(best,opt[buy][i]+shop[f][i].dist(hole[f]));
  75. }
  76. else best=pos.dist(hole[f]);//不用买气球的话就直接走到下一层的洞口
  77. d+=best;//累加距离
  78. pos=hole[f];//起点位置变为下一层的洞口处
  79. }
  80. printf("%.2lf\n",d);
  81. return ;//提高AC率的隐藏语句
  82. }

【动态规划】天堂(Heaven) 解题报告的更多相关文章

  1. [置顶] 刘汝佳《训练指南》动态规划::Beginner (25题)解题报告汇总

    本文出自   http://blog.csdn.net/shuangde800 刘汝佳<算法竞赛入门经典-训练指南>的动态规划部分的习题Beginner  打开 这个专题一共有25题,刷完 ...

  2. 【NOIP2015】提高day2解题报告

    题目: P1981跳石头 描述 一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N ...

  3. 【第40套模拟题】【noip2011_mayan】解题报告【map】【数论】【dfs】

    目录:1.潜伏者 [map] 2.Hankson的趣味题[数论]3.mayan游戏[dfs] 题目: 1. 潜伏者(spy.pas/c/cpp)[问题描述]R 国和S 国正陷入战火之中,双方都互派间谍 ...

  4. 2011 ACM-ICPC 成都赛区解题报告(转)

    2011 ACM-ICPC 成都赛区解题报告 首先对F题出了陈题表示万分抱歉,我们都没注意到在2009哈尔滨赛区曾出过一模一样的题.其他的话,这套题还是非常不错的,除C之外的9道题都有队伍AC,最终冠 ...

  5. ZOJ 1093 Monkey and Banana (LIS)解题报告

    ZOJ  1093   Monkey and Banana  (LIS)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid= ...

  6. 【原创】leetCodeOj --- Sliding Window Maximum 解题报告

    天,这题我已经没有底气高呼“水”了... 题目的地址: https://leetcode.com/problems/sliding-window-maximum/ 题目内容: Given an arr ...

  7. poj1173 解题报告

    poj1173 解题报告2013-07-21 13:31 by 期待 ., 42 阅读, 0 评论, 收藏, 编辑 http://poj.org/problem?id=1173 发现此题资料甚少,斗胆 ...

  8. [NOIP2013 花匠] 新人解题报告

    本来按照老师的要求,我学OI的第一份解题报告应是在寒假完成的关于数据结构的基础题,但由于身体原因当时未能完成,那么就在省选赛前临时写几篇吧…… 题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿 ...

  9. Leetcode 115 Distinct Subsequences 解题报告

    Distinct Subsequences Total Accepted: 38466 Total Submissions: 143567My Submissions Question Solutio ...

随机推荐

  1. GCDTimer

    #import <Foundation/Foundation.h> @interface JKTimerManager : NSObject + (instancetype)sharedT ...

  2. Repeater 动态增加删除一行

    文章参考:文章参考http://www.cnblogs.com/dataadapter/archive/2012/06/25/2562885.html 效果: 前台代码: <%@ Page La ...

  3. PHP 学习笔记 (三)

    stream_context_create()函数的用法: $url = "http://www.someweb.com" $context = stream_context_cr ...

  4. VS番茄助手安装(vs2015+vs2010):卸载之前的vs助手再安装新版本

    1 卸载之前的vs助手 vs2010: vs2015: 2 安装新版本

  5. window FILES——windows文件管理相关实例

    C语言下有一套文件管理方案.C++语言下也有一套自己的文件管理方案.windows系统当然也有自己的一套文件管理方案啦.对于普通char类型为基础的字符使用哪种方案的解决办法都是一样的,但是对于宽字符 ...

  6. A transition animation compatible Library.

    Android5.0之后为我们提供了许多炫酷的界面过渡效果,其中共享元素过渡也是很有亮点的一个效果,但这个效果只能在Android5.0之后使用,那今天我们就来将共享元素过渡效果兼容到Android4 ...

  7. InstallShield:自己备份

    LIST listData;//声明listData listData = ListCreate(STRINGLIST);//创建一个空的实际字符串或数字列表. //参数都是在上个界面中赋值,然后在下 ...

  8. web常用正则表达式

    1. 平时做网站经常要用正则表达式,下面是一些讲解和例子,仅供大家参考和修改使用: 2. "^\d+$" //非负整数(正整数 + 0) 3. "^[0-9]*[1-9] ...

  9. 鸟哥的linux私房菜——第20章 启动流程、模块管理与loader

    20.1 Linux启动流程分析 Linux启动过程: 按下开机电源后计算机硬件主动读取BIOS来加载硬件信息以及硬件系统的自我测试,之后系统会主动读取第一个可启动的设备(由BIOS设置),此时就可以 ...

  10. iOS: 学习笔记, 使用performSelectorOnMainThread及时刷新UIImageView

    在iOS中, 界面刷新在主线程中进行, 这导致NSURLSession远程下载图片使用UIImageView直接设置Image并不能及时刷新界面. 下面的代码演示了如何使用 performSelect ...