uva 1543 Telescope

来源:互联网 发布:听小说的软件 编辑:程序博客网 时间:2024/05/17 23:40

终于找到一点自信,没有看别人题解ac这道lrj紫书上的题目,一旦想到用海伦公式其他的就很简单了,我发现用递归写dp,真的比循环写dp要容易些。主要思路就是dfs函数中的循环语句。其实这道题目也可以看做搜索类的题目,状态转移方程式是dp[i][j][n]表示在i,j点中取n个节点的最大面积(i,j必取),dp[i][j][n] = max(dp[k][j][n-1]+area[i][k][j]) 其中i+1<= k <= j-1.就是这样简单的思路,有点想石子合并中一些思路。

题目链接:https://vjudge.net/problem/UVA-1543

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;const double pi = 3.14159265358979323846;const int maxn = 60;int n , m;double point[maxn];double area[maxn][maxn][maxn];double dp[maxn][maxn][maxn];double getangle (int i , int j) {double tmp = abs(point[i]-point[j]);return tmp > 0.5 ? 1-tmp : tmp;}double getarea (int i , int j , int k) {double aij = getangle(i,j)*pi , ajk = getangle(j,k)*pi , aki = getangle(k,i)*pi;double eij = sin(aij)*2 , ejk = sin(ajk)*2 , eki = sin(aki)*2;double p = (eij+ejk+eki)/2;return sqrt(p*(p-eij)*(p-ejk)*(p-eki));}void initarea () {for (int i = 1 ; i <= n ; i++)for (int j = i+1 ; j <= n ; j++)for (int k = j+1 ; k <= n ; k++) area[i][j][k] = getarea(i, j, k);}double dfs (int i , int j , int n) {double ans = 0;if (dp[i][j][n]) return dp[i][j][n];if (n == 0) return 0; for (int k = i+1 ; k <= j-1 ; k++)if (j-k > n-1) ans = max(ans , dfs(k, j, n-1)+area[i][k][j]);return dp[i][j][n] = ans; }int main () {while (scanf("%d%d" , &n , &m) != EOF && n && m) {memset(area,0,sizeof(area));memset(dp,0,sizeof(dp));memset(point,0,sizeof(point));double ans = 0;for (int i = 1 ; i <= n ; i++) scanf("%lf" , &point[i]);initarea();for (int i = 1 ; i <= n ; i++)for (int j = i+m-1 ; j <= n ; j++) ans = max(ans , dfs(i,j,m-2)); printf ("%.6lf\n" , ans);}}


0 0