这道题是“石子合并”的变形。同样是用动态规划来解。
用 dp[i, j] 表示从第 i 堆开始的 j 堆混合物合并所释放的最少烟雾量
sum[i, j] 表示从第 i 堆开始的 j 堆混合物合并后的颜色。
然后就有
dp[i][j] = min(dp[i][k] + dp[i+k][j - k] + sum[i][k]*sum[i+k][j-k]);
k from 1 to j - 1;
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define MAXN 110
int stone[MAXN], sum[MAXN][MAXN], dp[MAXN][MAXN];
int main(){
int t;
int n;
while(scanf("%d",&n)!= EOF){
memset(sum, 0, sizeof(sum));
memset(dp, 0, sizeof(dp));
for( int i = 1; i <= n; i++ ){
scanf("%d",&stone[i]);
sum[i][1] = stone[i];
}
for( int i = 1; i <= n; i++)
for( int j = 2; i + j <= n + 1; j++)
sum[i][j] = (sum[i][j-1] + stone[i + j - 1])%100;
for( int i = n; i >= 1; i--){
for( int j = 2; i + j <= n + 1; j++){
int maxn = 0x1f1f1f;
for( int k = 1; k < j; k++){
int tem = dp[i][k] + dp[i + k][j - k] + sum[i][k] * sum[i + k][j-k];
if(tem < maxn)
maxn = tem;
}
dp[i][j] = maxn;
}
}
printf("%d\n",dp[1][n]);
}
return 0;
}