Chinaunix首页 | 论坛 | 博客
  • 博客访问: 65406
  • 博文数量: 115
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-08 19:09
文章分类
文章存档

2015年(115)

我的朋友

分类: Python/Ruby

2015-08-06 16:51:33

《编程珠玑》第二章习题
给定一个n元实数集合、一个实数t和一个整数k,如何快速确定是否存在一个k元子集合,其元素之和不超过t?
 
O(n log k) 
Step 1.选取0..k-1元素填充数组r,用二分法插入。
Step 2.然后从k个元素开始,与结果中的元素比较,才用二分法插入.此时数组r共k+1个元素。去除r中最后一个元素。
Step 3.重复step 2直至结束。
 
算法复杂度:插入元素时,用二分法。其复杂度为log k. 共有n个元素, 其复杂度为O(n log k).
 
O(nk) 
若step 2中采取顺序插入,则其复杂度为O(nk);
 
用冒泡法排序,排k趟,其复杂度为O(nk);
 
 
这个二分法写的好烂啊。。无语。蠢死。

点击(此处)折叠或打开

  1. my @n;
  2. my @r;
  3. my $k = 5;
  4. my $t = 10;
  5. for(0..100){
  6.     $n[$_] = int(rand(100));
  7. }
  8. print "input : @n \n";
  9. print "--------------------------------------------\n";


  10. for(0..$k-1){
  11.     $r[$_] = 10000;
  12. }


  13. for my $cur (@n){

  14.     my $start = 0;
  15.     my $end = $k-1 ;
  16.     my $tindex ;
  17.     my $mid;

  18.     while(1){
  19.         $mid = int(($end+$start)/2);

  20.         if($cur>=$r[$mid] and $cur<= $r[$mid+1])
  21.         {
  22.             $tindex = $mid + 1;
  23.             last;
  24.         }
  25.         if($start+1 == $end){
  26.             $tindex = $end;
  27.             if($cur <= $r[$start]){
  28.                 $tindex = $start;
  29.             }
  30.             elsif($cur> $r[$end]){
  31.                 $tindex = $end +1;

  32.             }
  33.             last;
  34.         }
  35.         else{
  36.             if($cur > $r[$mid+1]){
  37.                 $start = $mid;
  38.             }
  39.             elsif($cur < $r[$mid]){
  40.                 $end = $mid;
  41.             }
  42.         }
  43.     }
  44.     next if($tindex >=$k);
  45.     for (my $i = $k -1 ; $i >= $tindex; $i--){
  46.         $r[$i] = $r[$i-1];
  47.     }
  48.     $r[$tindex] = $cur;
  49. }
  50. my $sum;
  51. for(@r){
  52.     $sum += $_;
  53. }
  54. print "@r \n" if($sum<=$t);

阅读(488) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~