zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    深入理解HTTP Session
    java中使用队列:java.util.Queue
    throws/throw Exception 异常应用
    Log4j实现对Java日志的配置全攻略
    java中volatile关键字的含义
    hibernate调用oracle存储过程||函数
    手势仿QQ侧滑---秀清
    归档和解档---秀清
    全局定义UINavigationContoller--By秀清
    重力感应 加速计- By严焕培
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/poj1651.html
Copyright © 2011-2022 走看看