木棍

木棍(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。

明显是一个贪心:

  统计每个长度所对应的木棍数,每两根一组,单出来的削下一个长度,放在下一个长度的数组中,但是要注意,每根木棒只能削一次

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<math.h>
#include<vector>
using namespace std;
int n,f[1000009],c,b[1000009];
int d[1000009],cnt;
int maxn=0;
long long ans;
int main()
{
    freopen("stick.in","r",stdin);freopen("stick.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&c);
        f[c]++;maxn=max(maxn,c);
    }
    for(int i=maxn;i>=2;i--)    
        if(f[i]%2==1&&f[i]!=b[i])    f[i]--,f[i-1]++,b[i-1]++;
    for(int i=maxn;i>=2;i--)
        while(f[i]>=2)    d[++cnt]=i,f[i]-=2;
    
    while(f[1]>=2)    d[++cnt]=1,f[1] -=2;
    for(int i=1;i<=cnt;i+=2)    
        ans=ans+1LL*d[i]*d[i+1];
    cout<<ans;
    return 0;
}
    
原文地址:https://www.cnblogs.com/CLGYPYJ/p/7227936.html