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 }
  • 相关阅读:
    js 压缩 预览 上传图片
    js base64 转成图片上传
    支付宝扫码转账
    js网页 唤醒支付宝
    URL 生成带文字二维码
    iOS-语言本地化
    iOS-Storyboad动态刷新
    iOS-UITouch,UIEvent使用介绍
    JSP-标准动作标记
    JSP-注释,脚本元素,指令
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/poj1651.html
Copyright © 2011-2022 走看看