官方题解是一个n2logn的dp做法

不过有一个简单易想的费用流做法

对每个小精灵,连边(A,i,1,pi) (B,i,1,ui) (i,t,1,0) (i,t,1,-pi*ui)

最后连边(s,A,a,0) (s,B,b,0)

跑最大费用最大流即可,注意精度误差

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 struct way{int po,next,flow;double cost;} e[40010];
 6 const double eps=1e-8;
 7 int pre[2010],p[2010],cur[2010],q[4000010];
 8 double d[2010],c[2010];
 9 bool v[2010];
10 int len,n,m,a,b,t;
11 
12 void add(int x,int y,int f,double c)
13 {
14      e[++len].po=y;
15      e[len].flow=f;
16      e[len].cost=c;
17      e[len].next=p[x];
18      p[x]=len;
19 }
20 
21 void build(int x,int y,int f,double c)
22 {
23      add(x,y,f,c);
24      add(y,x,0,-c);
25 }
26 
27 bool spfa()
28 {
29      for (int i=1; i<=t; i++) d[i]=-1e20;
30      memset(v,0,sizeof(v));
31      d[0]=0;
32      int f=1,r=1;q[1]=0;
33      while (f<=r)
34      {
35            int x=q[f++];
36            v[x]=0;
37            for (int i=p[x]; i!=-1; i=e[i].next)
38            {
39                int y=e[i].po;
40                if (e[i].flow&&d[x]+e[i].cost-eps>d[y])
41                {
42                   d[y]=d[x]+e[i].cost;
43                   pre[y]=x; cur[y]=i;
44                   if (!v[y])
45                   {
46                      q[++r]=y;
47                      v[y]=1;
48                   }
49                }
50            }
51      }
52      return d[t]>-1e20;
53 }
54 
55 double cost()
56 {
57     double s=0;
58     while (spfa())
59     {
60           s+=d[t];
61           for (int i=t; i; i=pre[i])
62           {
63               int j=cur[i];
64               e[j].flow--;
65               e[j^1].flow++;
66           }
67     }
68     return s;
69 }
70 
71 int main()
72 {
73     len=-1;
74     memset(p,255,sizeof(p));
75     scanf("%d%d%d",&n,&a,&b);
76     t=n+3;
77     for (int i=1; i<=n; i++)
78     {
79         scanf("%lf",&c[i]);
80         build(n+1,i,1,c[i]);
81         build(i,t,1,0);
82     }
83     for (int i=1; i<=n; i++)
84     {
85         double x;
86         scanf("%lf",&x);
87         build(n+2,i,1,x);
88         build(i,t,1,-c[i]*x);
89     }
90     build(0,n+1,a,0);
91     build(0,n+2,b,0);
92     printf("%.5lf\n",cost());
93 }
View Code

 

posted on 2017-02-04 14:57  acphile  阅读(151)  评论(0编辑  收藏  举报