POJ 1651:Multiplication Puzzle 区间DP

Multiplication Puzzle

题目链接:

http://poj.org/problem?id=1651

题意:

给出n个数字,从中取出n-2个,每取出一个,分数就会加上该数字和相邻两个数字的乘积(不能取左右两端的数字),求分数和最小值。

 

题解:

设dp[i][j]为区间[i,j]内取出j-i-1个数字的最小分数和,可以知道此时 i 和 j 为区间的左右端点,那么dp[i][j]的值就是在(i,j)内选一k值使得dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]最小,这个最小值就是dp[i][j]的最终值,终点状态为dp[1][n]

              

代码

#include<stdio.h>
#include<string.h>
const int N=101;
int dp[N][N],a[N];
int mmin(int x,int y)
{
  return x<y?x:y;
}
void solve()
{
  int n;
  while(~scanf("%d",&n))
  {
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=n;++i)
      scanf("%d",&a[i]);
    for(int len=2;len<n;++len)
    {
      for(int i=1;i+len<=n;++i)
      {
        int j=len+i;
        for(int k=i+1;k<j;++k)
        {
          if(a[i]*a[k]*a[j]+dp[i][k]+dp[k][j]<dp[i][j]||!dp[i][j])
          dp[i][j]=a[i]*a[k]*a[j]+dp[i][k]+dp[k][j];
        }
      }
    }
    printf("%d\n",dp[1][n]);
  }
}
int main()
{
  solve();
  return 0;
}

 
posted @ 2016-08-08 16:03  kiuhghcsc  阅读(170)  评论(0编辑  收藏  举报