TCO2012Round1B-1-FoxAndKgram


题目大意:
     利用int[] len表示一系列铅笔的长度,利用这些铅笔组成k-gram图案。k-gram图案的定义如下:
  • 拥有k行
  • 每行为一根长度为k的铅笔或者两个长度和为k-1的铅笔
     问:最大的k取值为多少。
     数据规模:铅笔数为[1,50],每根铅笔的长度为[1,50]。

思路:
     数据规模很小,所以直接从大到小遍历k的可能取值。显然k不会超过铅笔的个数,所以遍历范围为len.length到1。对于每一种k尝试构造该k-gram图。构造过程也比较简单,外层循环遍历每一根铅笔,如果正好长度为k则增加一行,如果长度小于k-1则通过内层循环寻找一个互补的铅笔共同构造一行,过程中用数组boolean[] used保存铅笔是否已使用的信息。如果最终构造的行数>=k则构造成功。该算法的计算复杂度为O(n^3),n为铅笔数。
     如果铅笔数的数据规模比较大,可以考虑对构图过程进行优化。使用一个数组int[] number表示各种长度的笔的个数,构造的计算复杂度为O(n)。然后遍历number的每一种长度,如果正好为k则将个数加到行数上;如果小于k-1则可以O(1)查找互补铅笔的个数,取二者个数的最小值。使用该构造方式后算法的计算复杂度优化为O(n*m),其中m为铅笔的最大长度。


Java代码:
public class FoxAndKgram
{
       public int maxK( int[] len)
      {
             int n = len.length ;
             for (int k = n; k >= 1; --k){
                int cnt = 0;
                boolean [] used = new boolean[n];
                for (int i = 0; i < n; ++i) if(!used[i]){
                    used[i] = true ;
                    if (len[i] == k){
                        cnt++;
                    } else if (len[i] < k - 1){
                        for (int j = i + 1; j < n; ++j) if(!used[j]){
                            if (len[j] + len[i] == k - 1){
                                used[j] = true ;
                                cnt++;
                                break ;
                            }
                        }
                    }
                }
                if (cnt >= k){
                    return k;
                }
            }
             return 0;
      }
}


      

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值