poj 1651 区间dp

题意:给出一组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("*****\n");
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\n",dp[0][n-1]);
49     }
50 }

 

posted @ 2015-05-10 17:12  miao_a_miao  阅读(124)  评论(0编辑  收藏  举报