zoukankan      html  css  js  c++  java
  • HDU 5135

    题意略。

    思路:

    本题开始我先写了一发dfs暴力,然而递归程度太深,导致爆栈。仔细回想一下dfs的过程,发现最不好处理的就是每收集到3个木棍,才能构成一个三角形。

    并且,还有一个隐患就是不能完全枚举出来木棍的组合情况。那么我们可以预先把木棍的组合情况枚举出来,按照题意,不会超过220种现在我们就是

    想在这些组合情况中谋求最大面积。这样,我们可以把这个题看成为一个特殊的背包问题。

    令dp[i][state]为在0~i中,当前恰好持有的木棍情况为state,且这些木棍要全部用完,我可以谋取的最大利益。那么状态转移方程为:

    dp[i][state] = max(dp[i - 1][state],dp[i - 1][state - 当前方案所需木棍情况] + area);

    详见代码:

    #include<bits/stdc++.h>
    #define maxn 251
    #define maxn1 5000
    using namespace std;
    
    struct node{
        double val;
        int state;
        node(double a = 0,int b = 0){
            val = a,state = b;
        }
    };
    
    double store[15];
    node depot[maxn];
    double dp[2][maxn1];
    int n;
    
    double cal(double a,double b,double c){
        double p = (a + b + c) / 2;
        return sqrt(p * (p - a) * (p - b) * (p - c));
    }
    bool judge(double a,double b,double c){
        return (fabs(a - b) < c && c < a + b);
    }
    void depart(int s){
        for(int i = 0;i < n;++i){
            if(s & (1<<i)) printf("1");
            else printf("0");
        }
    }
    
    int main(){
        while(scanf("%d",&n) == 1 && n){
            for(int i = 0;i < n;++i) scanf("%lf",&store[i]);
            int tail = 0;
            for(int i = 0;i < n;++i){
                for(int j = i + 1;j < n;++j){
                    for(int k = j + 1;k < n;++k){
                        double a = store[i],b = store[j],c = store[k];
                        if(!judge(a,b,c)) continue;
                        depot[tail++] = node(cal(a,b,c),(1<<i) | (1<<j) | (1<<k));
                    }
                }
            }
            for(int i = 0;i < 2;++i){
                for(int j = 0;j < maxn1;++j) dp[i][j] = -1;
            }
            dp[0][depot[0].state] = depot[0].val;
            dp[0][0] = 0;
            int total = (1<<n);
            for(int i = 1;i < tail;++i){
                for(int s = 0;s < total;++s){
                    dp[i & 1][s] = dp[(i - 1) & 1][s];
                    if(depot[i].state != (s & depot[i].state) || dp[(i - 1) & 1][s - depot[i].state] == -1) continue;
                    dp[i & 1][s] = max(dp[i & 1][s],dp[(i - 1) & 1][s - depot[i].state] + depot[i].val);
                }
            }
            double ans = 0;
            for(int s = 0;s < total;++s){
                ans = max(ans,dp[(tail - 1) & 1][s]);
            }
            printf("%.2lf
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    纹理加载和异步
    地板上创建批量小方块
    创建自定义几何体(以立方体为例)
    WTForms
    angular和vue的差别
    vuejs简单介绍特点
    angularjs简单介绍和特点
    flask重要点
    redis
    DRF之认证组件源码解析
  • 原文地址:https://www.cnblogs.com/tiberius/p/9164168.html
Copyright © 2011-2022 走看看