专栏文章

UVA1543 圆和多边形 Telescope 题解

UVA1543题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@min5qpr1
此快照首次捕获于
2025/12/01 21:00
3 个月前
此快照最后确认于
2025/12/01 21:00
3 个月前
查看原文
首先把多边形划分成同起点的多个三角形,那么我们显然可以动态规划,令 dpi,j,kdp{i,j,k} 表示起点为 ii 终点为 jj 选了 kk 个的最大值,那么转移方程为 dpi,nxt,k+1=max(dpi,nxt,k+1,dpi,j,k+S)dp_{i,nxt,k+1} = \max(dp_{i,nxt,k+1},dp_{i,j,k} + S),其中 SS 表示新加入的三角形面积,由起点 ii,旧终点 jj 和新终点 nxtnxt 构成,接下来只要看怎么求解面积即可。
首先可以发现,给出的实数代表与周长的比值,可以转化为与 2π2\pi 之间的比值,这里使用弧度制,因为圆的半径为一,那么接下来转化为已知角的大小 α\alpha,求在单位圆上对应的点的坐标,显然为 (cosα,sinα)(\cos \alpha,\sin \alpha),求解出三个点对应的坐标后利用海伦公式算出面积即可。
需要分别枚举起点 ii,旧终点 jj,新终点 nxtnxt 和个数 kk,时间复杂度量级为 O(n4)O(n^4)
CPP
#include<bits/stdc++.h>
using namespace std;
const double pi = acos(-1);
int n,m;
double p[45];
double dp[45][45][45];
double ans;
pair<double,double> trans(int i){//把第i个点转化为坐标形式
    double a = 2 * pi * p[i];
    return {cos(a),sin(a)};
}
double dis(double x1,double y1,double x2,double y2){//计算欧几里得距离
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
double cal(int a,int b,int c){//海伦公式计算由三个点构成的三角形的面积
    pair<double,double> A = trans(a);
    pair<double,double> B = trans(b);
    pair<double,double> C = trans(c);
    double AB = dis(A.first,A.second,B.first,B.second);
    double BC = dis(B.first,B.second,C.first,C.second);
    double AC = dis(A.first,A.second,C.first,C.second);
    double p = (AB + BC + AC) / 2;
    return sqrt(p * (p - AB) * (p - BC) * (p - AC));
}
int main(){
    while(cin >> n >> m && (n || m)){
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++){
            cin >> p[i];
        }
        for(int i=1;i<=n-m+1;i++){
            for(int j=i+1;j<=n;j++){
                for(int k=2;k<m;k++){
                    for(int p=j+1;p<=n;p++){
                        dp[i][p][k + 1] = max(dp[i][p][k + 1],dp[i][j][k] + cal(i,j,p));
                    }
                }
            }
        }
        ans = 0;
        for(int i=1;i<=n-m+1;i++){
            for(int j=i+1;j<=n;j++){
                ans = max(ans,dp[i][j][m]);
            }
        }
        cout << fixed << setprecision(6) << ans << "\n";
    }
    return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...