`
viking.liu
  • 浏览: 53649 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用5,7,12加减运算,求最少步数得到任意数n

阅读更多
package www.viking.com.algorithm;

public class MinSteps {

	/**
	 * @param args
	 *            5,7,12加减运算表示任意n的最少个数
	 * 
	 *            也就是 5x+7y+12z=n
	 * 
	 *            求|x|+|y|+|z|的最小值
	 * 
	 *            方法一:动态规划的思想
	 * 
	 *            首先正数和负数的性质一样的,所以只考虑正数的情况
	 *            我们用f(n)表示所有的组合方式的5、7、12的最少的个数,因为组合方式有无限多种,我们只关心
	 *            最少的个数,要尽量向n减小的方向递归。 f(n)=min{f(n-5),f(n-7),f(n -12)}+1;
	 *            f(0)~f(12)是已知的
	 * 
	 *            动态规划的性能非常低,当n为3位数的时候就已经很慢了
	 * 
	 * 
	 *            方法二:另外一种更简单的方法,枚举法
	 * 
	 *            5x+7y+12z=n要使|x|+|y|+|z|的最小值,那么z要尽量的大, 所以x和y就有取值范围了 |x|<7,
	 *            |y|<12. 因为如果x>=7那么 5x=5(x-7)+5*7其中y=5,x-7+5肯定比x小,所以|x|一定小7
	 *            同理|y|<12。 用枚举法求出最少的|x|+|y|+|z|就可以了。
	 * 
	 * 
	 */
	public static void main(String[] args) {
		int n = -100;

		int step[] = { 5, 7, 12 };
		if (n < 0) {
			step[0] = -5;
			step[1] = -7;
			step[2] = -12;
		}
		int min1 = minSteps(n, step, "=" + n);
		int min2 = minSteps(n);
		System.out.println(min1 + " " + min2);
	}

	public static int minSteps(int n, int[] step, String path) {
		if (n == 5 || n == 7 || n == 12) {
			//System.out.println(n + path);
			return 1;
		} else if (n < 12 && n >= 0) {
			// 0=5-5
			// 1=5+5+5-7-7
			// 2=7-5
			// 3=5+5-7
			// 4=7+7-5-5
			// 6=7+7+7-5-5-5
			// 8=5+5+5-7
			// 9=7+7-5
			// 10=5+5
			// 11=7+7+7-5-5
			if (n == 0) {
				System.out.println("5-5" + path);
				return 2;
			}
			if (n == 1) {
				System.out.println("5+5+5-7-7" + path);
				return 5;
			}
			if (n == 2) {
				System.out.println("5-7" + path);
				return 2;
			}
			if (n == 3) {
				System.out.println("5+5-7" + path);
				return 3;
			}
			if (n == 4) {
				System.out.println("7+7-5-5" + path);
				return 4;
			}
			if (n == 6) {
				System.out.println("7+7+7-5-5-5" + path);
				return 6;
			}
			if (n == 8) {
				System.out.println("5+5+5-7" + path);
				return 4;
			}
			if (n == 9) {
				System.out.println("7+7-5" + path);
				return 3;
			}
			if (n == 10) {
				System.out.println("5+5" + path);
				return 3;
			}
			if (n == 11) {
				System.out.println("7+7+7-5-5" + path);
				return 5;
			}
		}
		int a[] = new int[3];
		a[0] = minSteps(n - step[0], step, "+" + step[0] + path);
		a[1] = minSteps(n - step[1], step, "+" + step[1] + path);
		a[2] = minSteps(n - step[2], step, "+" + step[2] + path);
		int min = a[0];
		for (int i = 1; i < a.length; i++) {
			if (a[i] != Integer.MAX_VALUE) {
				if (a[i] < min) {
					min = a[i];
				}
			}
		}
		if (min == Integer.MAX_VALUE) {
			return Integer.MAX_VALUE;
		}
		return min + 1;
	}

	public static int minSteps(int n) {
		if (n == 0) {
			System.out.println("0=(5-5)");
			return 2;
		}
		int z = 0;
		int min = Integer.MAX_VALUE;
		int num = 0;
		for (int x = -6; x < 7; x++) {
			for (int y = -11; y < 12; y++) {
				int rest = n - x * 5 - y * 7;
				if (rest % 12 == 0) {
					z = rest / 12;
					// x、y、z不能同时为负数
					// 因为只能做加减法,5、7、12都是整数,至少有一个数为整
					if (x > 0 || y > 0 || z > 0) {
						num = Math.abs(x) + Math.abs(y) + Math.abs(z);
						if (num < min && num != 0) {
							System.out.println(n + "=(" + x + "*5)+(" + y
									+ "*7)+(" + z + "*12)");
							min = num;
						}
					}
				}
			}
		}
		return min;
	}
}

分享到:
评论

相关推荐

    计算机组成原理之补码加减运算器

    本资源主要讲解计算机组成原理中的补码加减运算器,包括加法器原理、补码加减运算和无符号数的加减运算。 一、加法器原理 加法器是一种基本的数字电路,可以实现两个n位二进制数的相加运算。加法器的输入包括两个n...

    任意大数的加减运算器

    "任意大数的加减运算器"是一个专门处理大数运算的程序或库,它能够处理超过普通整型变量所能表示的最大数值。下面将详细讨论大数运算的基本概念、实现方法以及相关技术。 首先,我们要理解什么是大数。在大多数编程...

    实现任意大整数的加减运算

    实现任意大整数的加减运算! input(&num1, &num2); num3= sum(&num1, &num2); output(&num1); if(num2.flag==0) printf("%c", '+'); else printf("%c", '-'); output(&num2); printf("= "); if(num3....

    线性表设计100位以内的长整数加减运算的程序

    "线性表设计100位以内的长整数加减运算的程序" 知识点一:链表的基本结构和操作方法 在设计一个100位以内的长整数加减运算的程序时,使用链表来表示长整数是一个不错的选择。链表的基本结构包括节点和指针,节点中...

    能够实现逻辑运算(逻辑非、逻辑加、逻辑乘、逻辑异)、定点整数的单符号位补码加减运算、定点整数的原码一位乘法运算和浮点数的加减运算

    能够实现逻辑运算(逻辑非、逻辑加、逻辑乘、逻辑异)、定点整数的单符号位补码加减运算、定点整数的原码一位乘法运算和浮点数的加减运算。

    一年级100以内加减混合运算口算题

    5. 一年级加减混合运算口算题的学习方法:一年级学生学习加减混合运算口算题时可以使用不同的学习方法,例如记忆法、计算法、解题法等等。 6. 加减混合运算口算题的类型:加减混合运算口算题可以分为不同的类型,...

    二年级100以内加减混合运算练习1000题.pdf

    6. 数字组合:通过加减法来组成或分解数,例如将15分解为10和5,或者通过加减运算得到特定的数字。 7. 快速计算技巧:培养学生的算数直觉,比如通过补数来简化减法计算,或是通过熟悉加法表来加快加法的速度。 8. ...

    汇编加减运算

    用于汇编语言中的加法和减法。通过减法可以得到正负值,及绝对值。

    大整数加减乘除运算

    本项目主要关注大整数的加减乘除运算的实现,这涉及到数据结构和算法的设计。以下是对这个课程设计项目的详细解读。 首先,我们要理解大整数的概念。在常规的计算机编程中,整数的大小受到数据类型限制,例如,int...

    一年级100以内加减混合运算练习600题-1年级加减法混合运算.pdf

    "一年级100以内加减混合运算练习600题-1年级加减法混合运算.pdf" 通过分析给定的文件信息,我们可以总结出以下知识点: 1. 加减混合运算:文件标题和描述中都提到了“加减混合运算”,表明该文件的主要内容是关于...

    基于条件结构实现两个数的加减乘除运算

    基于条件结构实现两个数的加减乘除运算

    C语言计算华容道移动最少步数

    《C语言实现华容道移动最少步数解析》 华容道,源于中国古代的棋类游戏,是一项极具挑战性的智力游戏。在这个问题中,我们关注的是如何利用C语言来计算解决华容道游戏的最少步数。C语言以其高效、简洁的特性,成为...

    ALU加减运算电路

    本项目提供了一个用Verilog语言编写的简单ALU加减运算电路,它能够处理四位二进制数的加减运算。Verilog是一种硬件描述语言,用于数字系统的建模,它允许设计者以结构化的方式描述硬件行为和结构。 在Verilog中,...

    五年级数学下册分数加减混合运算综合练习题100.pdf

    同时,如果加减运算的结果是假分数,我们通常还会将其化为带分数或整数加分数的形式,这样更容易理解和使用。 在具体练习题中,可能会出现各种实际问题,如计算物品的分配、时间的换算等,这些应用问题有助于学生...

    五年级小数加减乘除混合运算计算题练习题集.doc

    该练习题集涵盖了小数的加减乘除混合运算、解方程和使用简便方法计算的小数混合运算等多方面的内容。 小数混合运算专项训练: 1. 解方程:本部分提供了多种类型的小数方程,如5x=450、12(6-x)=42、1.2×6+4x...

    《10以内数的加减混合运算》说课稿子.pdf

    《10以内数的加减混合运算》是青岛版一年级数学上册第三单元的重要内容,旨在帮助学生理解和掌握10以内数的加减混合运算的原理和方法。本节课的目标不仅是让学生掌握运算技能,更是要培养他们的逻辑思维能力和解决...

    scratch加减法混合运算器电子学会图形化编程scratch等级考试四级真题解析2020-12.pdf

    scratch加减法混合运算器电子学会图形化编程scratch等级考试四级真题解析2020-12.pdf 本资源是一个scratch加减法混合运算器电子学会图形化编程scratch等级考试四级真题解析,涵盖了scratch编程的基本概念和实现方法...

Global site tag (gtag.js) - Google Analytics