N个数,求小于K的最大子序列之和

曾几何时,姐姐我一看到这样的题目就倍感头痛。然而,昨日受到启发,忽然想起了模仿二级制可以表示穷举法。兴奋得彻夜难眠,一早就爬起来,实现了该代码。
具体分析如下:
首先,题目有两个判断因素:小于N,最大。
我想到了一个做笨的方法,将N个数所有可能的子序列相加,看看每个之和是否小于k,如果满足这个条件,就放入result中。接下来,每次循环,得到的和都跟result进行比较。只要它小于k并且大于result,就将最新的和赋值给result。
那么如何模拟穷举呢?
我今天忽然想起了,一个n位数,如果每位上都可能是0、1,把所有的0、1排列都组合起来,那么就囊括了所有情况。也就是说,只要模拟出n位数的所有二进制效果,就能得到所有的子序列的可能性。利用这个二级制表示所有可能性,只要是位数上是1的,就把该位对应的那个数加进sum里。每轮循环都是一个不同的二进制数,当所有的二进制跑完一遍,各种可能性都走过了,实现了穷举。
ok,穷举表示的方法解决了,那么就可以动手写代码了。
C语言代码如下:
#include <stdio.h>
#include <stdlib.h>

int multi(int n){
  int i,k=1;
  for(i=1;i<=n;i++){
    k=k*2;
  }
  return k;
}

int qiongju(int *list,int start,int end,int standard){
  int bit = end-start+1,result=0;
  int count=0,j,maxOfAllBit=0;
  for(j=0;j<bit;j++){
    maxOfAllBit += multi(j);
  }
  printf("the all bit max:%d\n",maxOfAllBit);
  int array[bit];
  int flag=0;
  while(count<=maxOfAllBit){
    int temp=count,i=0;
    do{
      array[i++]= temp%2;
      temp = temp/2;
      }while(temp>0 && i<bit);
    while(i<bit){
      array[i++]=0;
    }
    int k,sum=0;
    for(k=0;k<bit;k++){
      printf("%d ",array[k]);
      if(array[k]==1){
        sum += list[k];
      }
    }
    printf("%d\n",sum);
    count++;
    if(sum<standard){
      if(flag == 0){
        result = sum;
        flag++;
      }
      else if(sum>result){
        result = sum;
      }
    }
  }
  return result;    
}

int  main(){
  //int array[10]={1,3,9,2,8,4,5,9,11,2};
  //int k = 27;
  int array[5]={4,1,3,6,7};
  int k=10;
  int result = qiongju(array,0,4,k);
  printf("%d\n",result);
  system("pause");
  return 0;
}



可以看到,我把每个二进制数产生的结果都打印出来了,每个二进制行的末尾多了一个数,是该行所有位数为1的二级位对应的数之和,方便自己调试查看的。
array就待计算数组,具体功能在qiongju函数中。
这个算法还有很多不完善的地方,有空我将进行下一步完善。

你可能感兴趣的:(二进制,穷举,小于k的最大子序列之和)