POJ 1948 Triangular Pastures 解题报告

来源:互联网 发布:王者荣耀mvp新算法 编辑:程序博客网 时间:2024/05/29 17:00

这道题我是用搜索做的。同时还用了个三维的数组记录状态。事实证明这种方法也是能过的,虽然时间是最久的。530ms+。

mark[i][a][b]表示从左往右扫描到第i个fence时,最小的边长度为a,第二小的边长度为b的情况是不是已经考虑过了。

因为每个fence要么在a里,要么在b里,要么在c里,实际有三种情况。但如果他们在第i步的时候状态完全相同,就只需要考虑一次就好了。

用到了一点点剪枝就是当最小的边a长度已经超过三边和的1/3时就没必要继续考虑了。

看了网上的解题报告,都是看做二维的0-1背包问题解的,我对动态规划的掌握还不够好,上来都是先想到搜索。。。

#include <iostream>#include <cmath>using namespace std;const int MAXN = 41;int fence[MAXN];bool mark[MAXN][MAXN * MAXN][MAXN * MAXN];int N, s;double hs;void recur(int i, int a, int b, double &maxt){if(a > s / 3 || mark[i][a][b]){return;}mark[i][a][b] = true;if(i == N){int c = s - a - b;if(a > 0 && b > 0 && c > 0 && a <= b && b <= c && a + b > c){double t = (hs - a) * (hs - b) * (hs - c);if(t > maxt){maxt = t;}}return;}recur(i + 1, a + fence[i], b, maxt);recur(i + 1, a, b + fence[i], maxt);recur(i + 1, a, b, maxt);}int main(){cin>>N;s = 0;for(int i = 0; i < N; ++i){cin>>fence[i];s += fence[i];}hs = s * 1.0 / 2;double maxt = -1;recur(0, 0, 0, maxt);if(maxt < 0){cout<<"-1"<<endl;}else{cout<<(int)(sqrt(maxt * hs) * 100)<<endl;}return 0;}