给定包含M 1的集合S(M),计算所有非空子集的集合,使得每个集合的并集生成S(M)。子集的基数也可以是K,其中1 <1。 K <= M和M可以取值达到10 ^ 5.
S(M) = {1,1,1,1}, K = 2.
possible collections can be
{{1,1},{1,1}},
{1},{1},{1,1}},
{{1,1},{1},{1}}
我已经看过几个答案,但我相信它们与我的不同。
我还阅读Stirling number of second kind但我仍然希望在该公式中纳入子集基数的条件。
我编写了一个可能的递归解决方案,该解决方案不适用于M的大值
如果有人需要更多信息,请告诉我。
任何帮助或指导都将不胜感激。
此致
的Ajay
答案 0 :(得分:0)
如果我正确地理解了这个问题中的术语,你会问有多少种方法将长度为 M 的序列ABCDEFGHIJ分成单词(例如,ABC DE FGH IJ ......)每个长度不大于 K 。 (对于给出的例子,答案是五:ABCD,AB CD,A BC D,AB CD和AB CD。)这是stars and bars解决的问题的双重问题,因为限制是在子集的大小而不是它们的数量。
我没有尝试使用封闭式解决方案,但直接dynamic programming攻击适用于O( M ^ 2 K ) time:让 C _n为第一个 n 字母的可能性。所有 n &lt; 0 C _0 = 1, C _n为0。对于 n &gt; 0,我们有 C _n = sum( i = [1 .. K ]) C _(名词 - I 的)。只需按顺序计算值,直到达到 C _M。 (当然,将最后的 K 值保留在用作SIPO shift register的队列中就足够了。)
请注意,值变得非常快: M = 100且 K = 2,我得到5.7e20的可能性;将 K 更改为10会产生6.1e29。提到的10 ^ 5的 M (再次 K = 2)得到4.2e20898。因此,我将 M 的额外因子包括在与任意精度算术相对应的复杂度中。
答案 1 :(得分:0)
方法应该是
Given M and K
Find the max number of divisions(subsets)
Find the min number of divisions(subsets)
Iterate from max to min using i
-Apply DP to find different combinations of sizes of subsets.
-A permutation of each combination should yield a count for that number of combinations(i).
-Sum up all the counts.
以下是带有DP的此逻辑的Java
实现。变量step
和toGo
分别对应M
和K
。我尝试用一些随机数运行它但是很低。
注意:您还需要更新静态数组维度 当使用巨大的M值时。
import java.util.Arrays;
public class HelloWorld{
public static int step = 4;
public static long[][] dMem = new long[100][100];
public static void main(String []args){
int toGo = 30;
int max = toGo;
int min = toGo/step;
long temp = 0;
long count = 0;
for(int i = max; i >= min; i--){
temp = nSteps(i, toGo);
temp = temp == -1 ? 0 : temp;
count += temp;
// System.out.println(count+"\n");
}
System.out.println("Num of ways = "+count);
}
public static long nSteps( int n, int toGo ){
long steps = 0, temp = 0;
//System.out.println(" n = "+n+" toGo = "+toGo);
if( n == toGo ) return 1;
if( n > toGo || n <= 0 || toGo <= 0) return -1;
if( dMem[n][toGo] != 0 ) return dMem[n][toGo];
for( int i = 1; i <= step; i++){
temp = nSteps( n-1, toGo-i );
temp = temp == -1 ? 0 : temp;
steps += temp;
}
steps = steps == 0 ? -1 : steps;
dMem[n][toGo] = steps;
return steps;
}
}