看似簡單實際很難的查找問題


所有的m位(二進制)數中找出n個數,使得任意2個數至少有k位不同。
對於給定的m,k(m>=k)求n的最大值?

25 个解决方案

#1


...up++  沒人

#2


 感覺其實也不是很難,至少有K位不同,即至少有K位上是(1,0).
 分析:
 假設有K位不同,即有K個(1,0),有M-K個(1,1)和(0,0),用排列組合來算,
 1.K位計算:C(k,m)種排列方式,每位上有兩種可能,即2^k,因為比較的兩個數實際上都在n中,所以再去掉重復情況,我們需要除以2, 則K位的種類為C(k,m)*2^(k-1);
 2.m-k位的情況為C(m-k,m);
 3.則K位相同的情況下有C(k,m)*2^(k-1)*C(m-k,m)種情況;
 4.依次類推K+1,K+2·····,m;
 5.求和得n。

 沒細想,稍微思考了下,可能不對,僅供參考

#3


int arr[m];

for (value in all)
{
for(i < m){
bit bits[m] = &value;
arr[i] += bits[i];
}
}

然后取出arr中的 最大的a個數,還有就是最小的b個數, a + b = k;
於是得出了這些數共同的k位。

然后。。。~

#4


這個編程序難度也許不大,不過證明似乎有些麻煩
建立一個臨時數組,先加入0,然后從0開始順序循環到2^m,如果這個數和每個臨時數組里面的數都滿足有k位不同則將該數加入臨時數組,最后統計臨時數組數目即可

#5


引用 4 樓  的回復:
這個編程序難度也許不大,不過證明似乎有些麻煩
建立一個臨時數組,先加入0,然后從0開始順序循環到2^m,如果這個數和每個臨時數組里面的數都滿足有k位不同則將該數加入臨時數組,最后統計臨時數組數目即可

個人覺得,問題難度在於每次都判斷是否滿足至少K位不同的條件,不是在於如何去循環·

#6


判斷是否有K位不同是否可以用異或來判斷?
引用 5 樓  的回復:
引用 4 樓  的回復:

這個編程序難度也許不大,不過證明似乎有些麻煩
建立一個臨時數組,先加入0,然后從0開始順序循環到2^m,如果這個數和每個臨時數組里面的數都滿足有k位不同則將該數加入臨時數組,最后統計臨時數組數目即可

個人覺得,問題難度在於每次都判斷是否滿足至少K位不同的條件,不是在於如何去循環·

#7


引用 6 樓  的回復:
判斷是否有K位不同是否可以用異或來判斷?
引用 5 樓  的回復:

引用 4 樓  的回復:

這個編程序難度也許不大,不過證明似乎有些麻煩
建立一個臨時數組,先加入0,然后從0開始順序循環到2^m,如果這個數和每個臨時數組里面的數都滿足有k位不同則將該數加入臨時數組,最后統計臨時數組數目即可

個人覺得,問題難度在於每次都判斷是否滿足至少K位不同的條件,不是在於如何去循環·
……

這個就需要每一位都去判斷了吧,會涉及移位,累加,異或,判斷等操作,如果M值很大,計算量將非常大,個人覺得應該避免這個問題

#8


如果只要最后結果,應該就是c(m,0)+c(m,k)+c(m,2*k)....c(m,n*k),其中n*k <=m && (n+1)*k >m
最終就是一個求組合數的問題

#9


引用 8 樓  的回復:
如果只要最后結果,應該就是c(m,0)+c(m,k)+c(m,2*k)....c(m,n*k),其中n*k <=m &amp;&amp; (n+1)*k >m
最終就是一個求組合數的問題

不對,想錯了。。。。

#10


2樓的思路不錯,有點算法設計的意思。

#11


引用 10 樓  的回復:
2樓的思路不錯,有點算法設計的意思。

一開始就錯了

#12


引用 10 樓  的回復:
2樓的思路不錯,有點算法設計的意思。


是錯了,沒考慮K+1位不同的數和K位不同的數之間可能不滿足條件,那LZ看看這樣行不行。后面m-k位也算的不對

先保證K位不同,即同前面:
1.K位計算:C(k,m)種排列方式,每位上有兩種可能,即2^k,因為比較的兩個數實際上都在n中,所以再去掉重復情況,我們需要除以2, 則K位的種類為C(k,m)*2^(k-1);
2.再去討論M-K位
  a.)其中沒有不同時種類有2^(m-k)
  b.)其中有1個不同時種類有2^(m-k-1)*C(1,k)
  c.)其中有2個不同時種類有2^(m-k-2)*[C(1,k)c(1,2)+c(2,k)*c(2,2)]
  ........
   其中有K個不同時種類有2^(m-k-k)*[C(1,k)c(1,k)+c(2,k)*c(2,k)...c(k,k)*c(k,k)]
  ........
   其中有j個不同時(j>k)種類有2^(m-k-j)*[C(1,j)c(1,j)+c(2,j)*c(2,j)...c(k,j)*c(k,j)]
3.1和2中和相乘

#13


是錯了,沒考慮K+1位不同的數和K位不同的數之間可能不滿足條件,那LZ看看這樣行不行。后面m-k位也算的不對

先保證K位不同,即同前面:
1.K位計算:C(k,m)種排列方式,每位上有兩種可能,即2^k,因為比較的兩個數實際上都在n中,所以再去掉重復情況,我們需要除以2, 則K位的種類為C(k,m)*2^(k-1);
2.再去討論M-K位
  a.)其中沒有不同時種類有2^(m-k)
  b.)其中有1個不同時種類有2^(m-k-1)-C(1,k)
  c.)其中有2個不同時種類有2^(m-k-2)-[C(1,k)c(1,2)+c(2,k)*c(2,2)]
  ........
  其中有K個不同時種類有2^(m-k-k)-[C(1,k)c(1,k)+c(2,k)*c(2,k)...c(k,k)*c(k,k)]
  ........
  其中有j個不同時(j>k)種類有2^(m-k-j)-[C(1,j)c(1,j)+c(2,j)*c(2,j)...c(k,j)*c(k,j)]
3.1和2中和相乘

(應該是減,但還是錯的,我哭····)

#14


哥們我糾結於此了,現在答案就是2^(m-k),只要n個數有至少k個共有的不同的位,顯然但K為最小時,n最大。(無法判斷答案正確與否)

求哪位大俠給正解,跪求啊·····

#15


引用 14 樓  的回復:
哥們我糾結於此了,現在答案就是2^(m-k),只要n個數有至少k個共有的不同的位,顯然但K為最小時,n最大。(無法判斷答案正確與否)

求哪位大俠給正解,跪求啊·····

要是有這么簡單的公式就好了
例如k=3:有
m=3 => n=2 (000和111)
m=4 => n=2
m=5 => n=4
m=6 => n=8
m=7 => n=16
m=8 => n=20 
顯然不符合公式!

#16


這題本來就不簡單啊。。

#17


很簡單,可惜不好證明。不過還是能夠證出來的。


#include <math.h> 
long find_n( m, k )
{
      return pow(2,(m-k+1));
}

#18


吃飯去,回來給你們證明一下哈:
find(m,k) = 2*find(m,k-1)
已知:
find(m,1) = 2^m
find(m,m) = 2

用數學歸納法就可以證明出來了。

#19


引用 18 樓  的回復:
吃飯去,回來給你們證明一下哈:
find(m,k) = 2*find(m,k-1)
已知:
find(m,1) = 2^m
find(m,m) = 2

用數學歸納法就可以證明出來了。

是要證明find(m,k) = 2*find(m,k+1)即可。
上面的寫錯了

#20


集合划分問題。
每個數與其他數之間的“位不同”作為他們的區別度。
現在是在指定區別度的情況下,查找最大集合。

#21


目測是簡單的二分圖匹配

#22


失誤,不是二分圖的匹配。

應該這樣建模:

枚舉任意兩個數,把每個數看做成一個節點,判斷是否至少有k位不同,若滿足,則連邊。

這樣轉換后,我們只需要求出這個圖的最大環有多少個節點即可。。。。


#23


也不對,我閉嘴,坐等高手。。。

#24


引用 22 樓  的回復:
失誤,不是二分圖的匹配。

應該這樣建模:

枚舉任意兩個數,把每個數看做成一個節點,判斷是否至少有k位不同,若滿足,則連邊。

這樣轉換后,我們只需要求出這個圖的最大環有多少個節點即可。。。。


是最大團,不是最大環,NP完全問題。

#25


引用 24 樓  的回復:
引用 22 樓  的回復:

失誤,不是二分圖的匹配。

應該這樣建模:

枚舉任意兩個數,把每個數看做成一個節點,判斷是否至少有k位不同,若滿足,則連邊。

這樣轉換后,我們只需要求出這個圖的最大環有多少個節點即可。。。。


是最大團,不是最大環,NP完全問題。


是的。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com