hdu 4412 2012杭州赛区网络赛 期望

虽然dp方程很好写,就是这个期望不知道怎么求,昨晚的BC也是

 

题目问题抽象之后为:在一个x坐标轴上有N个点,每个点上有一个概率值,可以修M个工作站,

                     求怎样安排这M个工作站的位置,使得这N个点都走到工作站的距离期望值最小?

解题报告人:SpringWater(GHQ)


解题思路:状态方程:dp[i][j]  =  min{ dp[i - 1][k - 1]  + cost[k][j]   }dp[i][j]表示在1到j修i个站,的最小期望值,

                   cost【k】【j】是我预处理的k到j这段区间修一个工作站的期望值 ,因为在求cost【k】【j】具

                有单调性,所以可以在O(n^2)复杂度算出

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<string.h>
 4 #include<map>
 5 #define INF ((1<<23)-1)
 6 using namespace std;
 7 map<int ,double> mp;
 8 double f[1010][60];
 9 typedef struct
10 {
11     int x; double p;
12 }Point;
13 Point pt[1010];
14 int kk,m;
15 
16 void initial()
17 {
18     for(int i=0;i<=1000;i++)
19         for(int j=0;j<=50;j++)
20             f[i][j]=INF;
21     for(int i=0;i<=m;i++)
22         for(int j=i;j<=m;j++)
23             f[i][j]=0.0;
24 }
25 
26 int main()
27 {
28     int k,i,j,l,x; double p;
29     while( scanf("%d%d",&kk,&m),kk+m )
30     {
31         mp.clear();
32         initial();
33         for(i=1;i<=kk;i++)
34         {
35             scanf("%d",&l);
36             for(j=1;j<=l;j++)
37             {
38                 scanf("%d%lf",&x,&p);
39                 mp[x]+=p;
40             }
41         }
42         map<int,double>::iterator it;
43         j=1;
44         for( it=mp.begin(); it!=mp.end();it++,j++)
45         {
46             pt[j].x=(it->first);
47             pt[j].p=(it->second);
48         }
49         int n=j-1;
50         for( i=1;i<=n;i++ )
51         {
52             for(j=1;j<=m && j<=i; j++ )
53             {
54                 f[i][j]=INF;
55                 double pre=0.000,suf=0.000;
56                 int cur=i; double add=0.000;
57                 for(k=i-1;k>=j-1;k--)
58                 {
59                     if( k+1 != i )
60                     {
61                         pre+=pt[k+1].p;
62                         add+=pt[k+1].p*(pt[cur].x-pt[k+1].x);
63                     }
64                     while( pt[cur].p+suf < pre )
65                     {
66                         suf+=pt[cur].p;
67                         cur--;
68                         pre-=pt[cur].p;
69                         add-=pt[cur].p*(pt[cur+1].x-pt[cur].x);
70                         add+=pt[cur+1].p*(pt[cur+1].x-pt[cur].x);
71                         add-=pre*(pt[cur+1].x-pt[cur].x);
72                         add+=(suf-pt[cur+1].p)*(pt[cur+1].x-pt[cur].x);
73                     }
74                     f[i][j]=min(f[i][j],f[k][j-1]+add);
75                 }
76             }
77         }
78         printf("%.2lf\n",f[n][m]);
79     }
80     return 0;
81 }

 

转载于:https://www.cnblogs.com/cnblogs321114287/p/4752651.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值