1. given a set, find a value such that the sum of the difference between all the elements in the set and the value is minimum.
e.g. given a set with element {a1,a2,a3,a4...an} and a value b we need to minimize abs(a1-b)+abs(a2-b)+...abs(an-b).
first step: sort set {a1,a2,...an}. find the middle element in the set. if the number of set elements is a odd value then the index of middle element is n/2 where index starts from 0 and in such case the value b is exactly the value of middle element in the set. if the number of set elements is even, then there are two middle elements in the set with index n/2, and n/2-1 in which case, the value b can be any element of these two elements.
2. given a set and each element in the set has a weight, then how to find the the element whose weighted difference from all the elements in the set is minimum.
the problem is different from the previous one in terms that each element in the set has a different weight. so how to deal with weight. we can use induction like this: f(i+1)=f(i)+(n1+n2-n3)*(s[i+1]-s[i]) where f(i) devotes the difference between the ith element and all the elements in the set and n1 devotes the weight of element before the ith element in the set and n1 devotes the weight of element at the index of i and n3 devotes the weight of element behind the ith element in the set. f(i+1) can be retrieved by adding f(i+1) to (n1+n2-n3)*difference between (i+1)th element and ith element.
3. about the problem the easiest way to deal with it is sum up weighted difference between the value we need and all the elements in the set.
有一个加权集合,找到一个元素使得这个元素与集合中的所有元素的加权距离最小。
f(i)表示所有元素与第i个元素的加权距离,则f(i+1)为:
f(i+1)=f(i)+(n1+n2-n3)*(s[i+1]-s[i]).其中n1表示在第i个元素前面的元素的个数,n2表示第i个元素个数,n3表示第i个元素后面的元素个数。当选择的元素从第i个元素变成了第i+1个元素后,第i个元素前面的所有元素的加权距离增加了n1*s[i+1]-s[i],第i个元素增加n2*s[i+1]-s[i],而第i个元素后面的元素的加权距离可以减少n3*s[i+1]-s[i],所有得到上面的公式
代码:
#include <algorithm> #include <iostream> int count[]={1,2,4,6,8,11,17}; int weight[]={1,2,1,1,1,1,2}; #define CNT 7 int calculateFloors(int floor){ int ts = 0; for(int i=0;i<CNT;i++){ ts+=abs(count[i]-floor)*weight[i]; } return ts; } int sort() { for(int i = 0; i < CNT;++i){ for(int j = 0;j<CNT-i-1;++j){ if(count[j]*weight[j]>count[j+1]*weight[j+1]){ std::swap(count[j],count[j+1]); std::swap(weight[j],weight[j+1]); } } } } inline int abs(int i){ return i > 0?i:-1; } int dispatch1(){ sort(); return count[CNT/2]; } int dispatch2() { int n1,n2,n3; n1=0; n2 = weight[0]; n3=0; int minFloor = 0; int min = 0; for(int i = 1;i<CNT;++i){ n3+=weight[i]; minFloor+=(count[i]-count[0])*weight[i]; } for(int i = 1;i<CNT;++i) { if(n1+n2<n3) { min = i; minFloor +=(n1+n2-n3)*(count[i]-count[i-1]); n1+=n2; n2=weight[i]; n3-=weight[i]; } else { break; } } return count[min]; } int dispatch3() { int ts= 0; int min = -1; int floor = 0; for(int i = 0; i< CNT;i++) { ts = 0; for(int j = 0; j < CNT;++j){ ts+=weight[j]*abs(count[i]-count[j]); } if(min == -1 || ts < min){ min = ts; floor = count[i]; } } return floor; } int main() { int ret = dispatch3(); std::cout<<"ret="<<ret<<std::endl; std::cout<<calculateFloors(ret)<<std::endl; }