**HDU 4412 - Sky Soldiers(区间DP)

来源:互联网 发布:网络消费者的需求特征 编辑:程序博客网 时间:2024/06/06 12:08

题目:

点击打开链接

题意:

有n个飞行员,每个飞行员都有c个落点和相应的概率,要建立m个补给站,使得n个飞行员到达补给站的期望值最小。

思路:

dp[i][j] 表示前i个落点建立j个补给站的最小期望值。

dp[i][j] = min(dp[k][j-1], cost[k][i] ) 。

cost[k][i] 表示区间(k,i)建立1个补给站供给此区间中的飞行员的期望值。

期望值 = (落点- 补给站)* 落点概率。

AC.

#include <iostream>#include <cstdio>#include <map>#include <algorithm>#include <cmath>#include <cstring>using namespace std;const double inf = 1e8*1.0;const int maxn = 1005;map<int, double> mp;double dp[maxn][80], cost[maxn][maxn];struct node {    double x, p;    bool operator < (const node & A) const {        return x < A.x;    }}num[maxn];int main(){    //freopen("in", "r", stdin);    int n, m;    while(~scanf("%d%d", &n, &m)) {        if(n == 0 && m == 0) break;        mp.clear();        for(int i = 0; i < n; ++i) {            int c, x;            double p;            scanf("%d", &c);            while(c--) {                scanf("%d %lf", &x, &p);                mp[x] += p;            }        }        int N = 1;        map<int, double>::iterator it;        for(it = mp.begin(); it != mp.end(); it++) {            num[N].x = it->first;            num[N++].p = it->second;        }        sort(num, num+N);        double fl, fr, pl, pr;        for(int i = N-1; i >= 1; --i) {            cost[i][i] = 0;            fl = fr = pl = pr = 0; // 期望 概率            pr = num[i].p;            int pos = i;            for(int j = i-1; j >= 1; --j) {                pl += num[j].p;                fl += num[j].p * (num[pos].x - num[j].x);                double temp = fl + fr;                while(temp > fl + fr + (pr - pl)*(num[pos].x - num[pos-1].x) && pos > 1) {                    pos--;                    fl -= pl*(num[pos+1].x - num[pos].x);                    fr += pr*(num[pos+1].x - num[pos].x);                    pl -= num[pos].p;                    pr += num[pos].p;                    temp = fl + fr;                }                cost[j][i] = temp;                //printf("pos = %d, (%d %d) %lf\n", pos+1, j, i, temp);            }        }        for(int i = 0; i < N; ++i) {            for(int j = 0; j <= m; ++j) dp[i][j] = inf;        }        dp[0][0] = 0;        for(int i = 1; i < N; ++i) {            for(int j = 1; j <= m; ++j) {                for(int k = i; k >= 1; --k) {                    dp[i][j] = min(dp[i][j], dp[k-1][j-1] + cost[k][i]);                }            }        }        printf("%.2lf\n", dp[N-1][m]);    }    return 0;}


0 0
原创粉丝点击