递归与分治策略——集合划分问题,众数问题

集合划分问题

n个元素的集合{1,2,.,n }可以划分为若干个非空子集。例如,当n=4 时,集合{1,2,3,4}可以划分为15个不同的非空子集如下:
{1}
{2}{3}{4}} {{12}{3}{4}}

{{1
3}{2}{4}} {{14}{2}{3}}

{{2
3}{1}{4}} {{24}{1}{3}}

{{3
4}{1}{2}} {{12}{34}}

{{1
3}{24}} {{14}{23}}

{{1
23}{4}} {{124}{3}}

{{1
34}{2}} {{234}{1}}

{{1
234}}

编程任务:
给定正整数n m,计算出n 个元素的集合{1,2,., n }可以划分为多少个不同的由m

非空子集组成的集合。

 

算法思路:

n个元素的集合可以划分为F(n,m)个不同的由m个非空子集组成的集合。
考虑3个元素的集合,可划分为

① 1
个子集的集合:{{12
3}}
② 2
个子集的集合:{{12}{3}}{{13}{2}}{{23}
{1}}
③ 3
个子集的集合:{{1}{2}
{3}}
F(3,1)=1;F(3,2)=3;F(3,3)=1;
如果要求F(4,2)该怎么办呢?

A.
里添一个元素{4},得到{{123}
{4}}
B.
里的任意一个子集添一个4,得到

{{1
24}{3}}{{12}{34}}

{{1
34}{2}}{{13}{24}}

{{2
34}{1}}{{23}{1
4}}

F(4,2)=F(3,1)+2*F(3,2)1+2*3
7

推广,得F(n,m)=F(n-1,m-1)+m*F(n-1,m)

public class SetPartition1 { public int F(int n,int m){ if(n<=2) return 1; if(m==1||n==m) return 1; else return F(n-1,m-1)+m*F(n-1,m); } public static void main(String[] args) throws IOException{ SetPartition1 sp = new SetPartition1(); int a; int s=0; String input; BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); input = stdin.readLine(); a = Integer.parseInt(input); for(int i=1;i<=a;i++){ int t = sp.F(a, i); s=s+t; } System.out.println(s); } }

众数问题

给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。例如,S={122235}。多重集S的众数是2,其重数为3

数据输入

输入包括多组数据,请处理到EOF结束。每组数据,以一个n(1<=n<=100,000)开始,接下n行,每行有一个数字(-231~231)

数据输出

对于每组输入数据,输出一行一个数字,表示众数。如果存在多个解,只需输出值最小的众数即可。

 

算法思路:首先用快速排序算法排序数组,找到当前数组的中位数及其位置,然后把在数组中与中位数相同的数字向它靠拢,就可以统计中位数的个数。现在数组已经被中间这些相等的数字分开了。那么递归条件就有了。如果中位数的个数比它左边这段短,那么说明左边有可能找到更多的,所以递归继续。反之,如果左边这段数的长度比较短,那么就没必要继续递归。对右边那段数据使用同样的策略。

 

 

 class ZS{ int element; //元素 int sum; //重数 } //记录中位数的起始下标 class Node{ int low; int high; } public class CountMode { public ZS x = new ZS(); void sort(int a[],int s,int t){ //对数组a进行快速排序 int i=s,j=t; int temp; if(si&&a[j]>temp) j--; if(i=0;j--){ if(med==a[j]){ m.high=j; break; } } return m; } //求众数 void mode(int a[],int l,int r){ if(l>=r) return; else{ Node n; int temp=0; int med; med=this.madian(a, l, r); n = this.spalit(a, med, l, r); temp=n.high-n.low+1; if(x.sumtemp){ if(x.sumtemp){ if(x.sum

 

 

你可能感兴趣的:(算法思考)