ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

第12届蓝桥杯 第七题:《砝码称重》的两种解法dfs和dp算法

2022-02-10 16:30:28  阅读:174  来源: 互联网

标签:count 12 int sum dfs 蓝桥 砝码 dp


第七题:《砝码称重》

题目大意

在这里插入图片描述

解题思路

思路1:用闫氏dp分析法:

在这里插入图片描述

思路2:dfs暴力搜索

dfs记住:找重复,找变化,找边界 来写dfs的函数。

预定义一个count数组,来存放0-100000的所有数据。每得到一个大于0的重量sum,就令count[sum] = 1。

最后打印count数组中为1的数,即可。

但是结果会超时,只能拿一半的分数。

private static void dfs(int x,int[] w,int sum,int[] count) {//下一个使用砝码的下标,砝码数组,当前用到砝码的总重量
			if (x == w.length) {
				if (sum > 0) {
					count[sum] = 1;
				}
				return;
			}
			dfs(x+1,w,sum+w[x],count);//加上第x个砝码
			dfs(x+1,w,sum,count);//不加第x个砝码
			dfs(x+1,w,sum-w[x],count);//减去第x个砝码
		} 

完整代码

代码1:用闫氏dp分析法:

import java.util.*;
//背包
public class Main {
	    public static void main(String[] args) {
	    	Scanner scanner = new Scanner(System.in);
	    	int N = 100;
	    	int n = scanner.nextInt();//砝码总数
	    	int[] w = new int[N+1]; //砝码大小
	    	int M = 200000;
	    	int B = M/2;
	    	int s = 0;//砝码总重量
	    	for (int i = 1; i <= n; i++) {//N个砝码的大小
				w[i] = scanner.nextInt();
				s += w[i];
			}
	    	boolean[][] dp = new boolean[N+1][M+1];
	    	dp[0][B] = true;
	    	//DP
	    	for (int i =1; i <= n; i++) {
				for (int j = -s; j <= s; j++) {
					dp[i][j+B] = dp[i-1][j+B];
					if (j-w[i] >= -s) {
						dp[i][j + B] |= dp[i-1][j - w[i] + B]; 
					}
					if (j+w[i] <= s) {
						dp[i][j + B] |= dp[i-1][j + w[i] + B];
					}
				}
			}
	    	
	    	int count = 0;
	    	for (int j =1 ; j <=s; j++) {
				if (dp[n][j+B]) {
					count++;
				}
			}
	    	System.out.println(count);
	    }
}

代码2:dfs暴力搜索

import java.util.*;
//dfs暴力
public class Main{
	static int N = 100;//最大砝码数
	static int M = 100000;//最大重量
	static int[] count = new int[M+1];
	    public static void main(String[] args) {
	    	Scanner scanner  = new Scanner(System.in);
	    	 int n = scanner.nextInt();//取的砝码数
	    	 int[] w = new int[n];
	    	for (int i = 0; i < n; i++) {
				w[i] = scanner.nextInt();//砝码的大小
			}
	    	//DFS
	    	dfs(0,w,0);
	    	//遍历count数组
	    	int s = 0;
	    	for (int i = 0; i < count.length; i++) {
				if (count[i] == 1) {
					s++;
				}
			}
	    	//打印结果
	    	System.out.println(s);
	    }
		private static void dfs(int x,int[] w,int sum) {//下一个使用砝码的下标,砝码数组,当前用到砝码的总重量
			// TODO Auto-generated method stub
			if (x == w.length) {
				if (sum > 0) {
					count[sum] = 1;
				}
				return;
			}
			dfs(x+1,w,sum+w[x]);//加上第x个砝码
			dfs(x+1,w,sum);//不加第x个砝码
			dfs(x+1,w,sum-w[x]);//减去第x个砝码
		}    
}

标签:count,12,int,sum,dfs,蓝桥,砝码,dp
来源: https://blog.csdn.net/m0_55846001/article/details/122863774

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有