CodeFoces 489E 01分数规划(二分的dp)

关于01分数规划:http://www.cnblogs.com/perseawe/archive/2012/05/03/01fsgh.html

算法很好,比较巧妙,尚未能深入理解。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 #define eps 1e-12
 7 
 8 double dp[1005];
 9 int d[1005],p[1005],n,l;
10 int pre[1005];
11 double check(double x)
12 {
13     int i,j;
14     double tmp;
15     memset(pre,0,sizeof(pre));
16     for (i=1;i<=n;i++)
17     {
18        dp[i]=1e10;
19         for (j=0;j<i;j++)
20             if (dp[j]+sqrt(abs(1.0*d[i]-d[j]-l))-x*p[i]<dp[i]){
21                 dp[i]=dp[j]+sqrt(abs(1.0*d[i]-d[j]-l))-x*p[i];
22                 pre[i]=j;
23             }
24     }
25     return dp[n];
26 }
27 void Print(int x)
28 {
29     if (pre[x]!=0) {
30             Print(pre[x]);
31             printf(" %d",x);
32     }
33     else printf("%d",x);
34 }
35 int main()
36 {
37     int i;
38     scanf("%d%d",&n,&l);
39     memset(pre,0,sizeof(pre));
40     dp[0]=0.0;
41     for (i=1;i<=n;i++)
42         scanf("%d%d",&d[i],&p[i]);
43     double left=0.0,right=10000000000.0;
44     while (right-left>eps)
45     {
46         double mid=(left+right)/2.0;
47         if (check(mid)>eps) left=mid;
48         else right=mid;
49     }
50     Print(n);
51 }
代码

链接:http://codeforces.com/contest/489/problem/E

posted on 2014-11-22 00:24  xiao_xin  阅读(152)  评论(0编辑  收藏  举报

导航