• hdu 4412 Sky Soldiers(区间DP)


    Sky Soldiers

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 559    Accepted Submission(s): 181


    Problem Description
    An airplane carried k soldiers with parachute is plan to let these soldiers jump off the plane along a straight air route. The landing point of these soldiers is undetermined because of various weather conditions. However, the statisticians of the army can analysis the probability of landing in a certain place through landing history records. To make it simple, the statistician suggests that these sky soldiers will land on finite discrete points of a straight line.

    This mission plans to place m provisions for the soldiers on the line for landing. These soldiers will be informed the direction of the nearest provision point by a special device after landing, and then walk to the point. The manager of this mission is asking you for help: to determine m points for provisions so that the expected sum of walking distance should be minimized. You can put provisions on any point of the landing line.
     

    Input
    There are multiple test cases. For each case, the first line contains two integers k and m (1 ≤ k ≤ 1,000, 1 ≤ m ≤ 50), which represent the number of sky soldiers and the number of positions to place provisions separately.

    The following k lines contain descriptions of landing parameters for the soldiers numbered from 1 to k. Each description consists of an integer L followed by L pairs of (x, p), which indicates that the probability of the soldier's landing on integer coordination x is p. It is guaranteed that all the p values are positive real numbers, and the sum of p in a single line is exactly 1. The same x may appear more than once on the same line which you should simply add up all the probability p of the pairs with equal x.
    The number of places on which all the soldiers could land is no more than 1000 and it can not be less than m.
    The input ends with k=m=0.
     

    Output
    For each test case, output a line containing only one real number which indicates the minimum expected sum of distance these soldiers will move and should be rounded to two digits after the decimal point.
     

    Sample Input
    2 1 2 0 0.5 1 0.5 2 1 0.1 3 0.9 0 0
     

    Sample Output
    2.30
     

    Source
     

    Recommend
    liuyiding   |   We have carefully selected several similar problems for you:  5053 5052 5051 5050 5049 
     
    题意:
    n个伞兵。落地后。每一个伞兵可能会落在若干个点上点都在x轴上。落在每一个点都有一个概率。如今在x轴上建立m个基地,每一个伞兵走到近期的基地。确定基地建立的地点使得全部伞兵所走的路程总和的期望最小。


    思路:

    乍一看像期望dp。细致思考后能够发现这是一个区间DP。如果一个伞兵落在x点。那么他走的路程的期望为p1*|x1-x|+p2*|x2-x|....*pm*|xm-x|。所以我们能够把n个伞兵等价成一个伞兵

    然后它到一个点的概率为全部伞兵到那点的概率总和。那如今就能够写出状态了。dp[i][j]表示在前i个位置建j个基地。

    该等效伞兵走的路程的最小期望。那么这题就类似poj 1160 Post Office那题了。转移方程为dp[i][j]=dp[k][j-1]+cost[k+1][i]。k<i。

    cost[i][j]表示在i,j之间建一个基地且该基地负责集合[i,j]上的伞兵。

    所走距离的期望。如今重点怎么高速算cost[i][j]了。考虑我们在算cost[j][i]的时候。随着j的减小基地的最优位置cur要么前移要么不变。所以我们就能够在O(n^2)的时间复杂度下算出了。

    具体见代码:

    #include<algorithm>
    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    #include<map>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int maxn=1010;
    typedef long long ll;
    struct node
    {
        int x;
        double p;
    } po[maxn];
    map<int,double> mp;
    map<int,double>::iterator it;
    int n,m;
    double dp[maxn][55],cost[maxn][maxn];
    int main()
    {
        int k,i,j,l,x,cur,dis;
        double p,lp,rp,cl,cr,tp;
    
        while(scanf("%d%d",&k,&m),k||m)
        {
            mp.clear();
            for(i=0;i<k;i++)
            {
                scanf("%d",&l);
                while(l--)
                {
                    scanf("%d%lf",&x,&p);
                    mp[x]+=p;
                }
            }
            n=0;
            for(it=mp.begin();it!=mp.end();it++)
            {
                po[++n].x=it->first;
                po[n].p=it->second;
            }
            for(i=n;i>=1;i--)
            {
                cost[i][i]=0;
                cur=i;
                rp=po[i].p;
                lp=0;
                cl=cr=0;
                for(j=i-1;j>=1;j--)
                {
                    dis=po[cur].x-po[j].x;
                    cl+=dis*po[j].p;//重心位置左边的期望和
                    lp+=po[j].p;//重心位置左边的概率和cr,rp为重心位置右边相应值
                    tp=cl+cr;//总期望
                    while(cur>1&&rp-lp<0)
                    {
                        dis=po[cur].x-po[cur-1].x;
                        cr+=dis*rp;
                        cl-=dis*lp;
                        cur--;
                        rp+=po[cur].p;
                        lp-=po[cur].p;
                        tp=cl+cr;
                    }
                    cost[j][i]=tp;
                    //printf("%d->%d tp %lf
    ",j,i,tp);
                }
            }
            for(i=0;i<=m;i++)
                dp[i][i]=0;
            for(i=1;i<=n;i++)
                dp[i][0]=1e15;
            for(j=1;j<=m;j++)
            {
                for(i=j;i<=n;i++)
                {
                    tp=1e15;
                    for(k=j-1;k<i;k++)
                        tp=min(tp,dp[k][j-1]+cost[k+1][i]);
                    dp[i][j]=tp;
                }
            }
            printf("%.2lf
    ",dp[n][m]);
        }
        return 0;
    }
    


  • 相关阅读:
    Oracle配置监听
    Oracle创建表空间和分配用户权限
    Dijkstra
    【刷题】【dp】【记忆化搜索】单词游戏
    【刷题】【记忆化搜索】【dp】Longtail Hedgehog
    【刷题】【dp】 Make The Fence Great Again
    【技巧】【卡常】
    【二分】【基础】(跳石头)(合并果子)(蚯蚓)
    【笔记】两种交换元素的方案对比
    【刷题】【单调栈】请客
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5355928.html
Copyright © 2020-2023  润新知