zoukankan      html  css  js  c++  java
  • 【动态规划】天堂(Heaven) 解题报告

    天堂(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=100+10,MAXN=100+10,MAXW=100+10,MAXQ=50+10;
    16 const double maxlen=0x7fffffff;//用极大值定义最远的距离 
    17 const double err=1e-3;
    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=0;}
    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=1;i<N;++i)scanf("%d%d",&hole[i].x,&hole[i].y);
    40     for(int i=1;i<N;++i)scanf("%d",W+i);
    41     for(int i=1;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(0,0);//pos储存当前所在的位置,初始在(0,0) 
    55     double d=0;//记录已经走过的距离 
    56     for(int f=1;f<N;++f)//循环计算每一层楼的情况 
    57     {
    58         int buy=M-W[f]>0?M-W[f]:0;//需要购买的气球数量,注意如果浮力大于体重则不需要购买,即购买数量为0 
    59         double best=maxlen;//动归过程中储存最优值的变量,初始为无穷大 
    60         if(buy) 
    61         {
    62             memset(opt,0,sizeof(opt));//每一层动归前,初始化数组 
    63             int border=shop[f].size();//邻接表的边界 
    64             for(int i=0;i<border;++i)
    65                 opt[1][i]=pos.dist(shop[f][i]);//给初始状态赋值 
    66             for(int i=2;i<=buy;++i)//以下为动归过程 
    67             for(int j=0;j<border;++j)
    68             {
    69                 opt[i][j]=maxlen;
    70                 for(int k=0;k<border;++k)if(k!=j)//题目中已经规定k不能与j相同 
    71                     opt[i][j]=min(opt[i-1][k]+shop[f][j].dist(shop[f][k]),opt[i][j]);
    72             }
    73             for(int i=0;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
    ",d);
    81     return 0;//提高AC率的隐藏语句 
    82 }
  • 相关阅读:
    负载均衡,会话保持,session同步
    UML类图关系大全
    web集群时session同步的3种方法
    Hive SQL count(distinct)效率问题及优化
    用C#开发蜘蛛网络爬虫采集程序(附源码)(二)
    前端检查Gridview中Checkbox列表并提示确认框
    jQuery处理JSON对象
    枚举的转换、遍历和绑定到DropDownList
    Cache缓存的遍历与清除所有缓存
    用C#开发蜘蛛网络爬虫采集程序(附源码)(一)
  • 原文地址:https://www.cnblogs.com/ringxu97/p/Heaven.html
Copyright © 2011-2022 走看看