题目链接:http://poj.org/problem?id=1651
思路:除了头尾两个数不能取之外,要求把所有的数取完,每取一个数都要花费这个数与相邻两个数乘积的代价,需要这个代价是最小的
用dp[i][j]表示区间[i,j]的最小代价,那么就有dp[i][j]=min(dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]) i+1<=k<=j-1
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<math.h> 5 #include<string.h> 6 #include<vector> 7 #include<queue> 8 #include<iterator> 9 #include<vector> 10 #include<set> 11 #define dinf 0x3f3f3f3f 12 typedef long long ll; 13 14 using namespace std; 15 16 int a[1005],dp[1005][1005]; 17 18 int main() 19 { 20 int num,i,j,k; 21 while(~scanf("%d",&num)) 22 { 23 for(i=0;i<num;i++) 24 scanf("%d",&a[i]); 25 for(i=0;i<num-2;i++) 26 dp[i][i+2]=a[i]*a[i+1]*a[i+2]; 27 int len; 28 for(len=3;len<num;len++) 29 for(i=0;i+len<num;i++) 30 { 31 j=i+len; 32 for(k=i+1;k<j;k++) 33 { 34 if(dp[i][j]==0) 35 dp[i][j]=dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]; 36 else 37 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]); 38 } 39 } 40 printf("%d ",dp[0][num-1]); 41 } 42 return 0; 43 }