(动态规划)Java实现最佳加法表达式求最小值

题目如下:

在一个n位整数a(只考虑正整数的情况)中插入r个加号,将它分成r+1个整数,找出一种加号的插入方法,使得这r+1个整数的和最小。

提示:动态规划求解

设f(i,k)表示在前i位数中插入k个加号所得和的最小值,a(i,j)表示从第i个数字到第j个数字所组成的j−i+1(i≤j)位整数值。

为了求f(i,k)的值,考察数字串的前i个数字,设前j(k≤j<i)个数字中已插入k−1个加号的基础上,在第j个数字后插入第k个加号,显然此时的最小和为f(j,k−1)+a(j+1,i)。于是可以得递推关系式:

f(i,k)=min(f(j,k−1)+a(j+1,i))    (k≤j<i)

前j个数字没有插入加号时的值显然为前j个数字组成的整数,因而得边界值为:

f(j,0)=a(1,j) (1≤j≤i)

代码如下:

package 实验测试;

import java.util.Scanner;

public class JS {
	public static void main(String args[]) {
		int m;
		int time;
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入整数串的长度以及需要加入的加号的个数");
		m = scanner.nextInt();
		time = scanner.nextInt();
		int a[] = new int[m];
		for(int i = 0; i < a.length; i++) {
			a[i] = (int)(Math.random()*10);
		}
		System.out.print("整数串为:");
		for(int i = 0; i < a.length; i++) {
			System.out.print(a[i]+"  ");
		}
		JSS b = new JSS();
		b.dp(a, time, m);
	}
}

class JSS{
	void dp(int a[], int t, int m) {
		int i,j,d,k,min;
		int max = 100;
		int O = 10000;
		int f[][] = new int[m+1][t+1];
		int num[][] = new int[m][m];
		for(i = 0; i < m; i++) {
			for(j = 0, d = 0; j < m; j++ ) {
				if(i > j)
					num[i][j] = O;
				else{
					d = d*10 + a[j];
					num[i][j] = d;
				}
			}
		}
		for(i = 1; i <= m; i++)
			for(j = 0; j<= t; j++) {
				if(j >= i)
					f[i][j] = O;
				else if(j == 0)
					f[i][j] = num[0][i-1];
				else {
					for(min = O, k = 1; k < i; k++) {
						f[i][j] = f[i-k][j-1] + num[i-k][i-1];
						if(min > f[i][j])
							min = f[i][j];
					}
					f[i][j] = min;
				}
			}
		System.out.println("最小值:"+f[m][t]);
	}
}

运行截图如下:

如有错误欢迎指出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值