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