Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 找到多个值的最接近极限组合的算法是什么?_Algorithm - Fatal编程技术网

Algorithm 找到多个值的最接近极限组合的算法是什么?

Algorithm 找到多个值的最接近极限组合的算法是什么?,algorithm,Algorithm,请告诉我解决此类问题的有效算法: 1) 有一个限制号码(例如100) 2) 有多个候选人(例如10、15、90、70、55) a) 我们需要选择1对[i,j],以便第i个和第j个候选项的总和最接近,但提示: 就一对而言 对所有值进行排序 使用两个“游标”从两端扫描;向左移动光标;如果总和超过限制数,请向右移动光标 例如 完成了 提示: 就一对而言 对所有值进行排序 使用两个“游标”从两端扫描;向左移动光标;如果总和超过限制数,请向右移动光标 例如 完成了 对于成对的情况: 您可以在O(

请告诉我解决此类问题的有效算法:

1) 有一个限制号码(例如100)

2) 有多个候选人(例如10、15、90、70、55)

a) 我们需要选择1对[i,j],以便第i个和第j个候选项的总和最接近,但提示:

就一对而言

  • 对所有值进行排序

  • 使用两个“游标”从两端扫描;向左移动光标;如果总和超过限制数,请向右移动光标

例如

完成了

提示:

就一对而言

  • 对所有值进行排序

  • 使用两个“游标”从两端扫描;向左移动光标;如果总和超过限制数,请向右移动光标

例如


完成了

对于成对的情况:

  • 您可以在O(NlogN)时间复杂度中找到此解决方案;其中N是元素列表的大小
  • 只需对列表进行排序
  • 然后从左侧拾取元素,并尝试查找剩余值 (已拾取关键点)使用二进制搜索。尝试查找所需的值 最接近剩余值,但不超过该值
  • 对所有N个元素执行此操作,您将找到其和为 最接近密钥的值(总和=STARTADR){ 时间总和=第一个元素+*(foundAddr-1); 临时配对=配对(第一个元素*(foundAddr-1)); } 如果(*foundAddr==剩余&&foundAddr>=startAddr),则为else{ temporarySum=第一个元素+*foundAddr; 临时配对=配对(第一个元素,*foundAddr); } 如果(临时总和>关闭最基本总和){ closestFoundSum=临时总和; pairForClosestSum=临时对; } }
    //对于成对的情况,返回总和最大的成对:

    • 您可以在O(NlogN)时间复杂度中找到此解决方案;其中N是元素列表的大小
    • 只需对列表进行排序
    • 然后从左侧拾取元素,并尝试查找剩余值 (已拾取关键点)使用二进制搜索。尝试查找所需的值 最接近剩余值,但不超过该值
    • 对所有N个元素执行此操作,您将找到其和为 最接近密钥的值(总和=STARTADR){ 时间总和=第一个元素+*(foundAddr-1); 临时配对=配对(第一个元素*(foundAddr-1)); } 如果(*foundAddr==剩余&&foundAddr>=startAddr),则为else{ temporarySum=第一个元素+*foundAddr; 临时配对=配对(第一个元素,*foundAddr); } 如果(临时总和>关闭最基本总和){ closestFoundSum=临时总和; pairForClosestSum=临时对; } }
      //将我编辑过的问题中金额最大的一对返回,以使其更易于理解。这就是你想问的吗?我只是简单地看了一下你的问题:对于a部分,你可以对候选人名单进行排序,即(10、15、55、70、90)。一旦得到排序后的候选列表,就可以放置两个计数器,一个在开头,一个在结尾。尝试一下这个,我想你们会想出解决办法的。b) 直觉上,它看起来像0-1背包,但我还没有证明这个翻译,我编辑了你的问题,使它更容易理解。这就是你想问的吗?我只是简单地看了一下你的问题:对于a部分,你可以对候选人名单进行排序,即(10、15、55、70、90)。一旦得到排序后的候选列表,就可以放置两个计数器,一个在开头,一个在结尾。尝试一下这个,我想你们会想出解决办法的。b) 直觉上,它看起来像0-1背包,但我还没有证明这个翻译
       10, 15, 55, 70, 90
        ^               ^
      
      #include <bits/stdc++.h>
      using namespace std;
      #define NEG_INFINITY -999999
      
      //In order to find a pair from item[] where the sumOfPair() <= key
      pair<int,int> findPair(int* item, int len, int key)
      {
          int* startAddr = item;
          int* endAddr = item + len;
          int firstElement, remaining;
      
          //Sort the given list
          sort(startAddr, endAddr);
      
          int closestFoundSum = NEG_INFINITY;
          int temporarySum;
          pair<int,int> pairForClosestSum = make_pair(NEG_INFINITY, NEG_INFINITY);
          pair<int,int> temporaryPair;
      
          /**
           * As the list is now sorted
              * for each element in the list starting from the left
              *   binary search for the remaining number in the remaining right partition of the list
              *   if any valid element is found
              *       check the sum, and always keep the largest sum that is <= key
          **/
          for(int i=0; i < len-1; i++)
          {
              firstElement = item[i];
              remaining = key - firstElement;
              startAddr = &(item[i]) + 1;
      
              int* foundAddr = lower_bound(startAddr, endAddr, remaining);
      
              if(foundAddr >= endAddr) foundAddr--;
      
              if(*foundAddr > remaining && foundAddr - 1 >= startAddr){
                  temporarySum = firstElement + *(foundAddr-1);
                  temporaryPair = make_pair(firstElement, *(foundAddr-1));
              }
              else if(*foundAddr == remaining && foundAddr >= startAddr){
                  temporarySum = firstElement + *foundAddr;
                  temporaryPair = make_pair(firstElement, *foundAddr);
              }
      
              if(temporarySum > closestFoundSum){
                  closestFoundSum = temporarySum;
                  pairForClosestSum = temporaryPair;
              }
          }
      
          //return the pair with the greatest Sum <= key
          return pairForClosestSum;
      }
      
      
      int main() {
          int item[] = {15,10,79,89,110};
          int len = 5;
          int key = 100;
      
          //For problem (a): Find a pair in the list with the closest sum to key; where sum <= key
          pair<int,int> resultPair = findPair(item, len, key);
          cout<<"Closest Sum of a Pair: " << resultPair.first<<" + "<<resultPair.second<<" = "<< resultPair.first + resultPair.second<<endl;
      
      }   
      
      #include <bits/stdc++.h>
      using namespace std;
      #define ResetArr(arr) memset(arr, -1, sizeof(arr))
      
      #define MAX_SIZE 10
      #define MAX_SUM 1000
      
      //memoization table
      int memo[MAX_SIZE][MAX_SUM];
      
      //list of elements
      int arr[MAX_SIZE];
      
      int findClosestSum(int index, int sumUptoIndex, int endIndex, int key){
          if(index >= endIndex){
              return sumUptoIndex;
          }
      
          //check memo table
          if(memo[index][sumUptoIndex] != -1){
              return memo[index][sumUptoIndex];
          }
      
          int sumConsideringIndex = 0;
          int sumAvoidingIndex = 0;
      
          //Check with taking element at 'index' into solution tuple
          if(sumUptoIndex + arr[index] <= key){
              sumConsideringIndex = findClosestSum(index+1, sumUptoIndex + arr[index], endIndex, key);
          }
      
          //Check without taking element at 'index' into solution tuple
          sumAvoidingIndex = findClosestSum(index+1, sumUptoIndex, endIndex, key);
      
          //take the sum that is closest and strictly less than key
          return memo[index][sumUptoIndex] = max(sumConsideringIndex, sumAvoidingIndex);
      }
      
      
      int main(){
          int size = 8;
          int key = 29;
      
          int arr2[size] = {5, 10, 17, 11, 12, 25, 4, 2};
      
          //fillup the list with given elements in arr2
          memcpy(arr, arr2, size * sizeof(int));
      
          //Do a 0/1 Knapsack Dp
          ResetArr(memo);
      
          cout<< "The closest {sum | sum <= key} = " << findClosestSum(0, 0, size, key) <<endl;
      
      }