【UVA1543】Telescope

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

给你一个圆和圆周上的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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值