【UVA1543】Telescope

来源:互联网 发布:关键词布局优化 编辑:程序博客网 时间:2024/06/07 17:14

题目描述

给你一个圆和圆周上的n(3=<n<=40)个不同的点。请选择其中的m(3<=m<=n)个,按照在圆周上的顺序连成一个m边形,使得它的面积最大。

Input

The input consists of multiple subproblems followed by a line containing two zeros that indicates the end of the input. Each subproblem is given in the following format.
n m p1 p2 ··· pn n is the number of points on the circumference (3 ≤ n ≤ 40). m is the number of vertices to form m-polygons (3 ≤ m ≤ n). The locations of n points, p1,p2,...,pn, are given as decimals and they are separated by either a space character or a newline. In addition, you may assume that 0 ≤ p1 < p2 < ··· < pn < 1.

Output

For each subproblem, the maximum area should be output, each in a separate line. Each value in the output may not have an error greater than 0.000001 and its fractional part should be represented by 6 decimal digits after the decimal point. 

Sample Input

4 3

0.0 0.25 0.5 0.666666666666666666667

4 4

0.0 0.25 0.5 0.75

30 15

0.00 0.03 0.06 0.09 0.12 0.15 0.18 0.21 0.24 0.27 0.30 0.33 0.36 0.39 0.42 0.45 0.48 0.51 0.54 0.57 0.61 0.64 0.66 0.69 0.72 0.75 0.78 0.81 0.84 0.87 40 20 0.351 0.353 0.355 0.357 0.359 0.361 0.363 0.365 0.367 0.369 0.371 0.373 0.375 0.377 0.379 0.381 0.383 0.385 0.387 0.389 0.611 0.613 0.615 0.617 0.619 0.621 0.623 0.625 0.627 0.629 0.631 0.633 0.635 0.637 0.639 0.641 0.643 0.645 0.647 0.649

0 0

Sample Output 

1.183013

2.000000

3.026998

0.253581

题解

运用三角形面积公式,S=0.5*a*b*sinc.dp[i][j][k]表示从i这个点开始,到j这个点,中间有k个点的最优解。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath> #define PI 3.14159265358979323846using namespace std;const int maxn=100;double a[maxn];double dp[maxn][maxn][maxn];double cal(double a,double b,double c){double x1=2.0*sin(PI*(a-b)),x2=2.0*sin(PI*(b-c));    return 0.5*x1*x2*sin(PI*(a-c));}int main(){int n,m;while(scanf("%d%d",&n,&m)==2&&n&&m){memset(dp,0,sizeof(dp));    for(int i=1;i<=n;i++){    scanf("%lf",&a[i]);    }    for(int p=3;p<=m;p++){for(int i=1;i<=n;i++)    for(int j=i+1;j<=n;j++)for(int k=i+1;k<=j-1;k++)        dp[i][j][p]=max(dp[i][k][p-1]+cal(a[j],a[k],a[i]),dp[i][j][p]);    }double ans=0;for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++)ans=max(ans,dp[i][j][m]);printf("%.6lf\n",ans); }return 0;}

原创粉丝点击