UVa:348 Optimal Array Multiplication Sequence

早就做出来了一直存在没发。

经典的区间DP。

时间复杂度O(n^3)三重循环分别枚举长度起点切点。

打印路径的思路出自算法导论。

 

 

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int s[20][20]= {0};
void Print_optimal_parens(int i,int j)
{
    if(i==j)
        printf("A%d",i);
    else
    {
        printf("(");
        Print_optimal_parens(i,s[i][j]);
        printf(" x ");
        Print_optimal_parens(s[i][j]+1,j);
        printf(")");
    }
}
int main()
{
    int N,kase=0;
    while(scanf("%d",&N)&&N)
    {
        int p[20]= {0};
        for(int i=1; i<=N; ++i) scanf("%d%d",&p[i-1],&p[i]);
        int dp[20][20]= {0};
        memset(s,0,sizeof(s));
        for(int l=1; l<N; ++l)
            for(int i=1; i+l<=N; ++i)
            {
                int j=i+l;
                for(int k=i; k<j; ++k)
                {


                    int res=dp[i][k]+dp[k+1][j]+p[i-1]*p[k]*p[j];
                    if(k==i) {dp[i][j]=res;s[i][j]=k;}
                    if(res<dp[i][j])
                    {
                        dp[i][j]=res;
                        s[i][j]=k;
                    }
                }
            }
        printf("Case %d: ",++kase);
        Print_optimal_parens(1,N);
        printf("\n");
    }
    return 0;
}


 

你可能感兴趣的:(动态规划,区间DP)