栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

2019蓝桥真题--质数拆分(动态问题01背包)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

2019蓝桥真题--质数拆分(动态问题01背包)

题目:质数拆分
将 2019 拆分为若干个两两不同的质数之和,一共有多少种不同的方法?

注意交换顺序视为同一种方法,例如2+2017=2019 与 2017 + 2 = 2019 视为同一种方法。

注:做题一定仔细读题,之前没看到两两不同,结果在哪里解了半天没解出来。

题解:
把2019拆分,反过来就是用若干个不同的质数组成值为2019的数。
每个数只取一次,刚好符合01背包问题。用f[i][j]表示用前i个数组成重量为j的方法数量,所以先打个素数表。

优化后的素数筛:

public static void sushubiao() {
		a[1]=true;//false代表i为素数。
		for (int i = 2; i*i < a.length; i++) {
			if(!a[i]) {
				for(int j = i*i;j 

打表:

int[] w = new int[2020];
		int k=1;
		for(int i =2;i<2020;i++) {
			if(!a[i]) {
				w[k++]=i;
			}
		}

实现01背包:如果不懂01背包点这里01背包的实现及优化
首先如果用i-1个数可以得到j,那么用i个数肯定也可以(因为数是从小到大排列,且i包含了[i-1]),所以每步要把f[i-1][j]赋值给f[i][j]
其次判断j是否大于w[i] 如果小于那么j里面肯定没有w[i]这个组成,例如j=7比w[i=5]小 (i代表是第五个质数w[5]=9),就不可以,如果是i=3,w[i]=5,f[3][7]就要加上f[2][7-5]

代码:

long[][] dp=new long[2030][2030];
		dp[0][0]=1;//dp[0][0]也是一种方法!!!!
		for(int i =1;i=w[i]) {
					dp[i][j]+=dp[i-1][j-w[i]];
				}
			}
		}
		System.out.print(dp[k-1][2019]);

完整代码如下:(没有优化空间,优化空间上面链接有方法)

public class Zhishu_dp {
	static boolean[] a = new boolean[3000];
	static long res =0;
	public static void main(String[] args) {
		sushubiao();
		int[] w = new int[2020];
		int k=1;
		for(int i =2;i<2020;i++) {
			if(!a[i]) {
				w[k++]=i;
			}
		}
		long[][] dp=new long[2030][2030];
		dp[0][0]=1;//dp[0][0]也是一种方法!!!!
		for(int i =1;i=w[i]) {
					dp[i][j]+=dp[i-1][j-w[i]];
				}
			}
		}
		System.out.print(dp[k-1][2019]);
		
	}
	public static void sushubiao() {
		a[1]=true;//false代表i为素数。
		for (int i = 2; i*i < a.length; i++) {
			if(!a[i]) {
				for(int j = i*i;j
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/764072.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号