hdu 4476 Cut the rope

10 篇文章 0 订阅

Cut the rope

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 206    Accepted Submission(s): 99


Problem Description
  Now we have some ropes. For each rope, you can cut it only once at any place, or you can also do nothing on it.  
  If we cut these ropes optimally, how many ropes we can get at most with the same length?
 

Input
  There is an integer T (1 <= T <= 100) in the first line, indicates there are T test cases in total.
  For each test case, the first integer N (1 <= N <= 100000) indicates there are N ropes. And then there are N integers whose value are all in [1, 100000], indicate the lengths of these ropes.
 

Output
  For each test case, you should output one integer in one line, indicates that the number of ropes we can get at most with the same length if we cut these ropes optimally.
 

Sample Input
  
  
3 1 1 2 1 2 3 2 3 3
 

Sample Output
  
  
2 3 5
Hint
  For Sample 1, we can get two ropes with 0.5 unit length.   For Sample 2, we can get three ropes with 1 unit length.   For Sample 3, we can get five ropes with 1.5 unit length
.
题意:n条绳子,每条绳子可以剪一次,也可以不剪,问最多能够得到多少条相同长度的绳子
解题思路:能够想到的一种做法是,枚举每条绳子一半的长度,求最大值。但是n到100000,直接暴力枚举会超时。
用s[i]表示小于等于i长的绳子数,如果当前枚举的绳子长度是a/2,则能够获取的最长相同长度绳子数为:总的绳子数n 减去比a/2短的绳子数;还应加上a长的绳子数,因为a长的绳子是对半截取,所以会多出一倍,最后求得最大值。
AC代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#define N 100005
using namespace std;
int main()
{
    int t,a,n,f[N],s[N];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        memset(f,0,sizeof(f));
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a);
            f[a]++;
        }
        s[0]=0;
        for(int i=1;i<N;i++)
        s[i]=s[i-1]+f[i];
        int max=0,t;

        for(int i=1;i<N;i++)
        {
            if(f[i]>0)
            {
              t=n-s[(i-1)/2]+f[i];
            if(t>max)
            max=t;
            }
        }
        printf("%d\n",max);
    }

return 0;
}

 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值