题目大意:混合n种混合物,每次只能混合相邻的混合物,每种混合物都有自己的颜色,每两种混合物混合后颜色会按一定的规律改变,并产生一定的烟雾,烟雾的大小与混合物的颜色有关系,求最小烟雾。
思路如下:n种混合物最终只剩下一种混合物,这种混合物由上一步剩下的两种混合物混合而成,因为每次只能混合相邻的混合物,所以这两种混合物一定分别是混合了【1,k】与【k+1,n】的混合物(1<=k<n),不会越界~~那混合n种混合物产生的最小烟雾就能由k确定了(能判断出这是动态规划了吧)。
动态转移方程dp[i][j]=Math.min(dp[i][j], dp[i][k]+dp[k+1][j]+a[i][k]*a[k+1][j]);dp[i][j]表示混合第 i 到第 j 种混合物产生的最小烟雾,a[i][j]表示第 i 种到第 j 种的所有混合物互相混合的颜色。
dp[i][k]+dp[k+1][j]+a[i][k]*a[k+1][j]就是说俩混合物的烟雾相加后,再加上混合产生的烟雾。
AC代码:
import java.util.Scanner;
public class Main
{
static Scanner scan=new Scanner(System.in);
public static void main(String[] args)
{
while(scan.hasNext())
{
int n=scan.nextInt();
int dp[][]=new int[n+1][n+1];
int a[][]=new int[n+1][n+1];
for(int i=1; i<=n; i++)
a[i][i]=scan.nextInt();//把颜色赋值到这a[i][i]代表第 i 种混合物的颜色
for(int i=1; i<=n; i++)
for(int j=1; i+j<=n; j++)
{
dp[j][j+i]=0x7fffffff;
for(int k=j; k<i+j; k++)//这就是上面提到的那个k了
if(dp[j][j+i]>dp[j][k]+dp[k+1][j+i]+a[j][k]*a[k+1][j+i])//如果找到更好的混合方法,就进去赋值
{
dp[j][j+i]=dp[j][k]+dp[k+1][j+i]+a[j][k]*a[k+1][j+i];
a[j][j+i]=(a[j][k]+a[k+1][j+i])%100;//确定dp[][]后,顺便把颜色给改了,其实不理解a数组也行,感觉只要把a数组跟dp数组的下标弄得一样就好
}
}
System.out.println(dp[1][n]);
}
}
}