Java实现 第十一届蓝桥杯——超级胶水(渴望有题目的大佬能给小编提供一下题目,讨论群:99979568)
PS:
好久没写过算法题了,如果发现错误还望大佬指出,
超级胶水
小明有n颗石子,按顺序摆成一排,他准备用胶水将这些石子黏在一起。
梅克什字有自己的重量,如果将两颗石子黏在一起,重量就是两个石子重量之和
为了粘贴牢固,该题认为两个石子粘连需要的胶水为两个石子的重量乘积。
每次只能合并相邻的两颗石子,并将合成的石子放在原来的位置,用最少的交水黏在一起,
请帮助小明计算最少需要多少胶水
输入:
n:石子的数量
n个整数w1,w2……wn,表示每颗石子的重量
输出:
最少的胶水数量
package 第十一届蓝桥杯; import java.util.Scanner; public class 超级胶水 { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int[] a = new int[1010]; int[][] dp = new int[1010][1010]; int[][] jiaoshui = new int[1010][1010]; //dp[i][j]代表从第i个到第j个石头合并的重量 //jiaoshui[i][j]代表从第i个到第j个石头合并的胶水量 for (int i=1; i<=n; i++) { a[i] = in.nextInt(); dp[i][i]=a[i]; } // for (int i=1; i<n; i++) { // for(int j=i+1; j<=n; j++) { // dp[i][j]=dp[i][j-1]+a[i]; // } // } //r是循环的范围,要从两个石头合并开始算,因为只有相邻的才能合并 for (int r=2; r<=n; r++) { //循环起始点,j就是从i向后r个范围的点j for (int i=1; i<=n-r+1; i++) { int j=i+r-1; jiaoshui[i][j] = Integer.MAX_VALUE; //这个是代表的用的哪个范围合并的石头,最后要加起来 int temp1 = 0; //这个是取两个相邻石头差值最大的拼凑 // 好比一共10个石头 // 差值小:一堆分五块 5*5=25 // 差值大: 一个1块一个9块 1*9=9 //胶水量形成了鲜明的对比,差值大的省胶水 int tempmax = -1; for (int k=i; k<j; k++) { if(tempmax< Math.abs(dp[i][k] - dp[k+1][j])){ //保存从哪里分开(哪两堆石头合并起来的) temp1=k; //dp[i][j]代表从第i个到第j个石头合并有重 dp[i][j] = dp[i][k] + dp[k+1][j]; //找差值最大的进行合并省胶水 tempmax=Math.abs(dp[i][k] - dp[k+1][j]); jiaoshui[i][j] = dp[i][k] * dp[k+1][j]; } } //如果jiaoshui[i][i]表示的是一个石头,一个石头粘连在一起是不需要胶水的,这里要跳过 if(i!=temp1) jiaoshui[i][j]+=jiaoshui[i][temp1]; if(temp1+1!=j) jiaoshui[i][j]+=jiaoshui[temp1+1][j]; } } //1-n粘连需要的最小胶水 System.out.println(jiaoshui[1][n]); } }