题意:
n个数字组成的序列,每次取出一个数字,这个数字不能是最左端或最右端的数字,取第i个数字需要的代价为a[i-1] * a[i] * a[i+1],最后只剩下最左端和最右端的数字。问最小代价是多少。3 <= n <= 100。
题解:
1.dp[i][j]表示[i , j]区间取完(i , j)区间的数字的最小代价。
2.dp[i][j] = min(dp[i][j] , dp[i][k] + dp[k][j] + a[i] * a[k] * a[j])。(i <= k <= j)
3.注意初始化。区间大小不同,初始化的内容不同。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 105
#define inf 0x3f3f3f3f
using namespace std ;
int main()
{
int i , j , k , d , l , r ;
int n ;
int a[N] ;
int dp[N][N] ;
scanf("%d" , &n) ;
for(i = 1 ; i <= n ; i ++)
scanf("%d" , &a[i]) ;
memset(dp , inf , sizeof(dp)) ;
for(i = 1 ; i <= n ; i ++)
dp[i][i] = 0 ;
for(i = 1 ; i <= n - 1 ; i ++)
dp[i][i + 1] = 0 ;
for(i = 1 ; i <= n - 2 ; i ++)
dp[i][i + 2] = a[i] * a[i + 1] * a[i + 2] ;
for(d = 3 ; d <= n - 1 ; d ++)
for(l = 1 ; l + d <= n ; l ++)
{
r = l + d ;
for(k = l ; k <= r ; k ++)
dp[l][r] = min(dp[l][r] , dp[l][k] + dp[k][r] + a[l] * a[k] * a[r]) ;
}
printf("%d" , dp[1][n]) ;
}