dp[i][j]表示区间i到j的最小消耗值
val[i][j]表示区间i到j在去最小消耗值的情况下所产生的材料值
设将i到i+k-1的区间先处理,再处理i+k到j区间,最后再合并,然后动态规划找最优
典型区间dp
方程
dp[i][j] = min{ dp[i][j] , dp[i][i+k-1] + dp[i+k][j] + val[i][i+k-1] * val[i+k][j] };
若 dp[i][j] 有被更新则还要更新val[i][j]的值
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <queue>
#include <map>
#define FOP freopen("in","r",stdin)
#define inf 0x3f3f3f3f
#define ll __int64
#define eps 1e-8
using namespace std;
const int N = 110;
int val[N][N];
int dp[N][N];
int main()
{
int T;
int i,j,k,l,n,tmp;
scanf( "%d" , &T );
while( T-- )
{
memset( val , 0 , sizeof val );
memset( dp , 0 , sizeof dp );
scanf( "%d" , &n );
for( i = 1 ; i <= n ; i++ ) scanf( "%d" , &val[i][i] );
for( i = 1 ; i <= n ; i++ )
for( j = i+1 ; j <= n ; j++ )
dp[i][j] = inf;
for( l = 1 ; l <= n-1 ; l++ )
{
for( i = 1 ; i <= n-l ; i++ )
{
j = i+l;
for( k = 1 ; k <= j-i ; k++ )
{
tmp = dp[i][i+k-1] + dp[i+k][j] + val[i][i+k-1] * val[i+k][j];
if( tmp < dp[i][j] )
{
dp[i][j] = tmp;
val[i][j] = ( val[i][i+k-1] + val[i+k][j] ) % 100;
}
}
}
}
printf( "%d\n" , dp[1][n] );
}
return 0;
}