求一个集合的所有子集问题实现

本文介绍了一种高效算法来解决一个数学问题:对于由1至N的正整数组成的集合,如何找出所有非空且元素不相邻的子集,并计算这些子集元素乘积的平方和。通过递推方法将复杂度从指数级降低到O(n)。

**问题描述
已知N个大于0的整数构成一个集合,即{1,2,3,……,N},求其所有的非空且元素不相邻的子集,计算所有子集的乘积的平方的和。
例如:集合{1,2,3,4},其所有非空不相邻子集有{1},{2},{3},{4},{1,3},{1,4},{2,4}
这些子集的乘积的平方和为:
11+22+33+44+(13)(13)+(14)(14)+(24)(2*4)
=1+4+9+16+9+16+64
=39+80
=119
请输入一个整数N(1<=N<=100),表示集合M中的N元素分别为1、2、……、N。输出一个数T,表示集合M中的所有非空不相邻子集中各元素乘积的平方和。
输入
4
输出
119

这题刚开始做的时候,我是用想用队列的方式写:
如开始时队列有
1------>1出队------->此时到2 2与1是相邻,所以不做处理,直接相加,此时为sum=1²+2²=5.
此时队列有2个数,此时到3,1出列与3不是相邻所以sum+=(1*3)²······
一直这样求下去,后来发现,到了双位数就不好处理,而且题目要求99,如此下去队列肯定会炸,而且时间复杂度过不去,算个1分钟结果也出不来的。所以就往另一个方向想。

后来想到的方法是,递推方法   如图:

这里写图片描述
n从1开始一直添加到n,从n=3开始,你会发现相邻的是不可能的,直接排除,相差2的,即为1的所有子集(包括自己)与3都是不相邻。n=5时,n=3符合、n=6时,n=4符合。。。依次递推下去
因此,复杂度一下子从指数级别下降到O(n),很强势!!
不过现在还有一个问题,就是大数处理,我这里用JAVA的大数,C/C++的话需要自己写一个大数乘法。
JAVA代码如下:

import java.math.BigInteger;
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sn = new Scanner(System.in);
		int n = sn.nextInt();
		sn.close();
		BigInteger a1 = new BigInteger("1");
		BigInteger a2 = new BigInteger("5");
		for(int i = 3;i<=n;i++){
			BigInteger ii = new BigInteger(i+"");
			BigInteger temp = a2.add(a1.add(BigInteger.ONE).multiply(ii.multiply(ii)));//递推式子,计算此次的和
			a1=a2;
			a2=temp;
		}
		System.out.println(n==1?1:a2.toString());//如果输入的n为1,则答案就为1,如果其他值输出a2的值
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值