poj1651 Multiplication Puzzle 区间DP

题目链接:http://poj.org/problem?id=1651

区间DP思想:

定义dp[i][j]表示区间(i,j)删除其中的所有元素后(当然是不包括i,j了啊)的最优值,那么

dp[i][j]=min(dp[i][k]+dp[k][j]),其中k为区间i,j中最后删除的元素,(i<k<j);

有了状态转移方程,实现起来就很方便了啊。

我用了迭代和记忆化搜索两种方式实现:

1,迭代代码(运行时间0Ms)

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 using namespace std;
 6 #define INF 10000100
 7 int dp[110][110];
 8 int a[110];
 9 void init()
10 {
11        for(int i=0;i<110;i++)
12                for(int j=0;j<110;j++)
13                        dp[i][j]=INF;
14         for(int i=0;i<110;i++) 
15                 dp[i][i+1]=0;
16         memset(a,0,sizeof(a));
17 }
18 int main()
19 {
20         int n;
21         while(scanf("%d",&n)!=EOF)
22         {
23                 init();
24                 for(int i=0;i<n;i++)
25                         cin>>a[i];
26                 for(int j=2;j<n;j++)
27                         for(int i=j-2;i>=0;i--)
28                                 for(int k=i+1;k<j;k++)
29                                     dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]);
30                 cout<<dp[0][n-1]<<endl;
31        }
32        return 0;
33 
34 }

2,记忆化搜索的方式(运行时间16MS)

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 using  namespace std;
 6 #define INF 100001000
 7 int dp[110][110];
 8 int a[110];
 9 int dfs(int i,int j)
10 {
11         int sum=0;
12         if(dp[i][j]<INF) return dp[i][j];
13         if(j==i+2) return dp[i][j]=a[i]*a[i+1]*a[j];
14         if(j==i+1) return dp[i][j]=0;
15         for(int k=i+1;k<j;k++)
16         {
17               sum=dfs(i,k)+dfs(k,j)+a[i]*a[j]*a[k];
18               dp[i][j]=min(dp[i][j],sum);
19         }
20         return dp[i][j];
21 }
22 int main()
23 {
24        int n;
25        while(scanf("%d",&n)!=EOF)
26        {
27                int sum;
28               for(int i=0;i<n;i++)
29                       scanf("%d",&a[i]);
30               for(int i=0;i<110;i++)
31                       for(int j=0;j<110;j++) dp[i][j]=INF;
32                   for(int k=1;k<n-1;k++)
33                   {
34                          sum=dfs(0,k)+dfs(k,n-1)+a[0]*a[n-1]*a[k];
35                          dp[0][n-1]=min(dp[0][n-1],sum);
36                   }
37                   cout<<dp[0][n-1]<<endl;
38        }
39        return 0;
40 }

 

posted on 2013-08-13 10:13  GyyZyp  阅读(216)  评论(0编辑  收藏  举报

导航