题意:给出一组N个数,每次从中抽出一个数(第一和最后一个不能抽),该次的得分即为抽出的数与相邻两个数的乘积。直到只剩下首尾两个数为止。问最小得分是多少?
链接:点我
转移方程:
dp[i][j]=dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]
这里的k一定是最后一步算的,所以乘以a[i]和a[j]
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3f3f3f; 11 const double eps=1e-5; 12 typedef long long ll; 13 #define cl(a) memset(a,0,sizeof(a)) 14 #define ts printf("***** "); 15 const int MAXN=1005; 16 int n,m,tt; 17 int a[MAXN],dp[MAXN][MAXN]; 18 int main() 19 { 20 int i,j,k; 21 #ifndef ONLINE_JUDGE 22 freopen("1.in","r",stdin); 23 #endif 24 while(scanf("%d",&n)!=EOF) 25 { 26 for(i=0;i<n;i++) 27 { 28 scanf("%d",a+i); 29 } 30 cl(dp); 31 for(i=0;i<n;i++) 32 for(j=i+2;j<n;j++) dp[i][j]=INF; 33 for(i=0;i<n-2;i++) 34 { 35 dp[i][i+2]=a[i]*a[i+1]*a[i+2]; 36 } 37 for(int len=3;len<n;len++) 38 { 39 for(i=0;i+len<n;i++) 40 { 41 j=len+i; 42 for(k=i+1;k<=j-1;k++) 43 { 44 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]); 45 } 46 } 47 } 48 printf("%d ",dp[0][n-1]); 49 } 50 }