`
viking.liu
  • 浏览: 54262 次
  • 性别: 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;
	}
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics