zoukankan      html  css  js  c++  java
  • [POJ] 1948 Triangular Pastures (DP)

    题目地址:http://poj.org/problem?id=1948

    题目大意:

    给N条边,把这些边组成一个三角形,问面积最大是多少?必须把所有边都用上。

    解题思路:

    根据题意周长c已知,求组合三边长使得三角形面积最大。如果直接DFS的话,每次考虑每根木棍放在哪一条边上,爆搜,可以加上每条边不会大于周长的一半的剪枝。根据数据规模,仍会超时,所以可以考虑采用动态规划。因为周长c已知,所以只需考虑其中两条边即可。类似二维0-1背包的做法,开一个二维判定数组f[i][j],i代表第一条边长为i,j为第二条边长为j,则第三条边长为c-i-j,判定所有情况。最后验证即可。因为三角形每条边长不可能超过周长的一半,所以枚举i,j最大到c/2即可。最后注意结果小数部分不是四舍五入,而是直接截断的,所以可以利用强制转化。

    DP代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    using namespace std;
    const int N=41*41;
    int f[N][N];
    int a[41],c=0,n;
    
    int main()
    {
        
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            c+=a[i];
        }
        
        memset(f,0,sizeof(f));
        f[0][0]=1;
        for(int i=1;i<=n;i++){
            for(int j=c/2+1;j>=0;j--){
                for(int k=c/2+1;k>=0;k--){
                    if(j-a[i]>=0 && f[j-a[i]][k]){
                        f[j][k]=1;
                    }
                    if(k-a[i]>=0 && f[j][k-a[i]]){
                        f[j][k]=1;
                    }
                }
            }    
        }
        
        double s=0;
        for(int i=c/2+1;i>=0;i--){
            for(int j=c/2+1;j>=0;j--){
                if(f[i][j]){
                    double la=i,lb=j,lc=c-i-j;
                    double p=(la+lb+lc)/2.0;
                    if(sqrt(p*(p-la)*(p-lb)*(p-lc))>s){
                        s=sqrt(p*(p-la)*(p-lb)*(p-lc));
                    }
                }
            }
        }
        
        printf("%d
    ",s==0 ? -1 : (int)(s*100));
        
        return 0;
    }

    DFS代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    using namespace std;
    const int N=53;
    int n,sum,la=0,lb=0,c=0,lc;
    int a[N],f[N];
    double s=0;
    
    void dfs(int k)
    {
        if(la>c/2 || lb>c/2 || lc>c/2) return ;
        if(k==n){ 
            if(la+lb>lc && la+lc>lb && lb+lc>la){
                double p=(la+lb+lc)/2.0;
                if(sqrt(p*(p-la)*(p-lb)*(p-lc))>s){
                    s=sqrt(p*(p-la)*(p-lb)*(p-lc));
                }
            }
            return ;
        }
        for(int i=0;i<n;i++){
                if(!f[i])
                for(int j=0;j<3;j++){
                    if(j==0){
                        la+=a[i];
                        f[i]=1;
                        dfs(k+1);
                        f[i]=0;
                        la-=a[i];
                    }
                    if(j==1){
                        lb+=a[i];
                        f[i]=1;
                        dfs(k+1);
                        f[i]=0;
                        lb-=a[i];
                    }
                    if(j==2){
                        lc+=a[i];
                        f[i]=1;
                        dfs(k+1);
                        f[i]=0;
                        lc-=a[i];
                    }
                }
        }
    }
    int main()
    {
        memset(f,0,sizeof(f));
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            c+=a[i];
        }
        dfs(0);
        printf("%d
    ",s==0 ? -1:(int)(s*100)); 
        return 0;
    }
  • 相关阅读:
    Leetcode Valid Sudoku
    Leetcode Surrounded Regions
    LeetCode Sqrt
    LeetCode POW
    LeetCode Next Permutation
    ACK-Ackermann, 阿克曼函数
    再不懂时序就 OUT 啦!,DBengine 排名第一时序数据库,阿里云数据库 InfluxDB 正式商业化!
    阿里云提供全托管 ZooKeeper
    性能压测中的SLA,你知道吗?
    第一个入驻阿里云自营心选商城,如今它已经是营收过亿的SaaS独角兽
  • 原文地址:https://www.cnblogs.com/sxiszero/p/5278085.html
Copyright © 2011-2022 走看看