题目:点击打开链接
题目大意:
给N条边,把这些边组成一个三角形,问面积最大是多少?必须把所有边都用上。
思路:
对于已知周长的三角形,我们只要知道两条边的长度变可推出第三条边,所以可以得到状态方程:
f[i][j][k] 表示用前i条边,能否组成长度为j和k的两条边
初始化f[0][0][0] = true;
f[i][j][k] = f[i-1][j-len[i]][k] || f[i-1][j][k-len[i]];
如果f[i][j][k]=true,那么就计算以j,k,sum-j-k为三条边能否组成三角形,如果可以就用海伦公式计算面积。
由于如果要开三维数组的话,要开f[40][1600][1600],明显是要MLE的,所以要降成二维的,
而时间复杂度40*1600*1600,如果没有优化直接上,是要TLE的。
所以要优化,根据优化的程度,运行时间可以再100MS~1000MS之间:
1. f[i][j] 和 f[j][i]是相同的两个三角形,所以递推时可以让 j>=i
2. 对于每条边,一定是小于周长的一半
3. 枚举到第i条边时, 前i条边不可能组成大于等于sum[i] (sum[i]=len[1]+...+len[i])的长度
优化了一下时间到了100MS+
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#define SQ(x) ((x)*(x))
#define MP make_pair
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
typedef long long int64;
using namespace std;
const int MAXN = 42;
int n, m;
int len[MAXN], sum[MAXN];
bool f[1602][1602];
inline bool isTriangle(double e[3]){
if(e[2] < e[1]){
swap(e[2], e[1]);
if(e[1] < e[0]) swap(e[0], e[1]);
}
return e[0]+e[1] > e[2];
}
inline double getArea(double e[3]){
if(!isTriangle(e)) return -1;
double p = sum[n]/2.0;
return sqrt(p*(p-e[0])*(p-e[1])*(p-e[2]));
}
int main(){
scanf("%d", &n);
for(int i=1; i<=n; ++i){
scanf("%d", &len[i]);
sum[i] = sum[i-1]+len[i];
}
memset(f, 0, sizeof(f));
f[0][0] = true;
double ans = -1;
double e[3];
for(int i=1; i<=n; ++i){
for(int v1=min(sum[i],sum[n]>>1); v1>=0; --v1){
for(int v2=min(sum[i]-v1,sum[n]>>1); v2>=v1; --v2)if(v1+v2<sum[n]){
e[0] = v1; e[1] =v2; e[2] = sum[n]-v1-v2;
if(v1-len[i]>= 0 && f[v1-len[i]][v2]){
f[v1][v2] = true;
}
if(!f[v1][v2] && v2-len[i]>=0 && f[v1][v2-len[i]]){
f[v1][v2] = true;
}
if(f[v1][v2]){
ans = max(ans, getArea(e));
}
}
}
}
if(ans < 0) puts("-1");
else printf("%d\n", (int)(100*ans));
return 0;
}
分享到:
相关推荐
### Poj 3342 (树状DP) #### 题目背景 这是一道典型的树状动态规划问题,来源于POJ平台编号为3342的题目。题目描述了一个公司的组织结构,并提出了一种特定场景下的最优解求法。 #### 题目解析 在题目描述中提到...
### poj dp总结:动态规划分类 #### 概述 动态规划(Dynamic Programming,简称DP)是一种在计算机科学和数学中广泛使用的算法策略,用于解决最优化问题。它通过将复杂问题分解为较简单的子问题来求解,并利用这些...
在POJ 2029这个题目中,我们可能面临的问题是需要对一个二维矩阵进行动态更新和求和查询,例如计算某一个矩形区域内的元素总和。 二维树状数组的基本思想是将二维空间转化为一维存储,通常是通过行优先或列优先的...
在本篇中,我们将深入学习二维树状数组的应用,并通过解决POJ 1195问题来实践这一概念。 POJ 1195题目要求我们计算一个二维矩阵中的子矩阵之和。这正是二维树状数组的优势所在,因为我们可以快速地对矩阵的任意矩形...
晒代码之二——多重背包(POJ1276)
题目要求通过划分一个二维矩阵为多个不重叠的矩形区域,使得每个矩形区域的平均值与整体平均值之差的平方和最小。这个问题可以通过构建一个多维数组来存储中间结果,避免重复计算,从而有效解决。 ### 关键代码分析...
在给出的文件列表中,“POJ1014-Dividing【多重背包+二进制优化】.cpp”和“POJ1014-Dividing【DFS】.cpp”很可能是两份不同的C++代码实现,分别展示了如何结合多重背包和二进制优化以及如何利用DFS来解决问题。...
标题中的"POJ3411-Paid Roads【class】"指的是一个编程竞赛问题,源自北京大学的在线评测系统POJ(Problem Online Judge)。这个题目可能涉及到道路付费的问题,需要通过编程来解决。"class"在这里可能指的是在解决...
* 哈希表和二分查找等高效查找法:哈希表和二分查找等高效查找法是指解决问题的高效查找算法,如 poj3349、poj3274、POJ2151、poj1840、poj2002、poj2503。 * 哈夫曼树:哈夫曼树是指解决问题的哈夫曼树算法,如 poj...
【标题】"POJ1015-Jury Compromise" 是一个编程竞赛题目,主要涉及的是动态规划(Dynamic Programming, 简称DP)的算法应用。动态规划是一种解决复杂问题的有效方法,它通过将问题分解成子问题,并存储子问题的解来...
### poj_dp分类解析 #### 概述 在本篇文章中,我们将深入探讨并解析PoJ (Pacific Ocean Judger) 平台上与动态规划(Dynamic Programming, DP)相关的题目分类及其特征。通过这些题目,读者可以更好地理解动态规划的...
* 哈希表和二分查找等高效查找法:例如 poj3349、poj3274、poj2151、poj1840、poj2002、poj2503。 * 哈夫曼树:例如 poj3253。 * 堆:例如 poj2513。 * trie 树:例如 poj2513。 4. 简单搜索: * 深度优先搜索...
动态规划 01背包问题 POJ3624可以AC
为解决这一问题,可以定义一个二维数组dp[i][w],表示前i件物品在不超过背包承重限制为w的情况下,可以获得的最大价值。 算法步骤如下: 1. 初始化dp数组。 2. 遍历所有物品,对于每件物品i,遍历所有可能的承重...
- 背包问题:如`poj1837, poj1276`。 - 简单DP:如`poj3267, poj1836`。 - **数学** - 组合数学:如`POJ3252, poj1850`。 - 数论:如`poj2635, poj3292`。 #### 第二阶段中级训练计划 #### 第3周至第4周(共...
可以用二维数组`dp[i][j]`表示前`i`个物品装入容量为`j`的背包中的最大价值,其中状态转移方程为`dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])`,这里`w[i]`和`v[i]`分别是第`i`个物品的重量和价值。...
在滑雪问题中,给定一个二维数组表示地形高度,任务是找出从任意一点开始能够滑行的最长下坡路径的长度。这里的“最长下坡路径”是指从一个点出发,每次只能滑向高度较低的相邻点,直到无法继续下滑为止。 实验要求...
POJ上的一道题目,自己写的代码,因为想下载别人的, 所以就放上了。
PKU Online Judge上面很全面的动态规划试题总结。动态规划是ACM考点中最重要的一大类算法之一,对于工作人员来说,动态规划也是实际开发中...这是POJ上面很多DP题目的总结与深刻分析。利于算法学习,学长给的,在此分享
背包之01背包、完全背包、多重背包详解 Dynamic+Programming 典型的动态规划,用递归下的记忆化搜索来实现 1088 POJ 动态规划加速原理之四边形不等式 基于连通性状态压缩的动态规划问题 对一些DP题目的小结 树型动态...