题目描述
给你一个圆和圆周上的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.14159265358979323846
using 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;
}

该问题要求从给定的圆周上多个点中选取一定数量的点,构成一个多边形,使得其面积最大。输入包含多个子问题,每个子问题给出点的数量n、需要构成的多边形顶点数m以及点的位置。输出每个子问题的最大面积,要求精度为六位小数。解题方法是利用三角形面积公式和动态规划策略。
375

被折叠的 条评论
为什么被折叠?



