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 }