zoukankan      html  css  js  c++  java
  • stick

    木棍(stick)
    Time Limit:1000ms Memory Limit:128MB

    题目描述
    LYK有很多木棍,具体的,总共有n根,且每根木棍都有一个长度。为了方便起见,我们可以用一个正整数ai表示第i根木棍的长度。
    LYK有一把小刀,但这把小刀由于削木棍很不方便,对于一根木棍而言,它只能用这把小刀削掉恰好1的长度。
    LYK觉得如果4根木棍头尾相连能恰好拼成长方形,说明这4根木棍是可以捆在一起卖钱的!具体的,如果这4根木棍的长度分别为a,b,c,d,如果满足a=b,c=d,说明恰好可以拼成长方形,且获得的钱为这4根木棍圈成的面积a*c。当然如果不能恰好拼成长方形,则卖不出去。
    LYK想将这些木棍尽可能的4个一组捆在一起去卖钱,它想知道最多能获得多少钱。

    输入格式(stick.in)
    第一行一个数n,表示木棍的个数。
    接下来一行n个数,第i个数ai表示第i根木棍的长度。

    输出格式(stick.out)
    一个数表示答案。

    输入样例
    12
    2 3 3 4 5 5 5 5 7 9 11 13

    输出样例
    31

    数据范围
    对于30%的数据n=4。
    对于50%的数据n<=20。
    对于70%的数据n<=1000。
    对于100%的数据1<=n<=100000,1<=ai<=1000000。

    解法:
    第一档前50%可能能用搜索来做(我一开始写了搜索但是不对啊)。
    这个题可以用贪心来做(正解啦)。
    对于同一长度的木棍,如果有奇数根(而且存在不是削下来的),就可以削掉一根,因为不削也没什么用处,削了或许有用。这样处理下来,最后一定是长的和长的搭配面积最大啦。
    代码:

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<vector>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int n,maxn;
    long long ans;
    int a[100009],b[1000009],c[1000009],cnt; 
    int main()
    {
        freopen("stick.in","r",stdin);
        freopen("stick.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++) 
          scanf("%d",&a[i]),b[a[i]]++,c[a[i]]++,maxn=max(maxn,a[i]);
    
        for(int i=maxn;i>=1;i--) 
          if(b[i]%2==1&&c[i]>0) b[i]--,c[i]--,b[i-1]++;
    
        for(int i=maxn;i>=1;i--) 
          while(b[i]>=2) a[++cnt]=i,b[i]-=2;
        if(cnt%2) cnt--;
        for(int i=1;i<=cnt;i+=2)
          ans+=1ll*a[i]*a[i+1];
        printf("%lld",ans);
        return 0;   
    }
    /*
    5
    55 55 53 52 50
    2860
    */
    /*
    5
    55 55 51 59 20
    0
    */
  • 相关阅读:
    设置iterm可配色
    Java权限管理
    npm添加淘宝镜像
    新版同义词
    maven打包加时间戳方法总结
    python中的实例方法、类方法、静态方法的区别
    15个流行的python框架
    python学习笔记
    前置声明和包含头文件的区别(待补充)
    数组和链表的时间复杂度
  • 原文地址:https://www.cnblogs.com/dfsac/p/7587895.html
Copyright © 2011-2022 走看看