ZOJ 1276 纪录路径的DP,生成括号的方法很有效

来源:互联网 发布:淘宝图片保护在哪里看 编辑:程序博客网 时间:2024/06/10 21:00

/*
source: ZOJ t1276
algorithm: dp(iterate)
author: wangmeng @ flame
date:2009.8.14

记录路径的DP。生成路径的一种方法
*/

#include<iostream>
using namespace std;

int a[11];                //store the rows and columns of all matrix
int dp[11][11] = {0};    //used for DP,the bellman equation: dp[l][i] =  min{dp[k][i] + dp[l-k][i+k] + a[i]*a[i+k]*[i+l]}
int way[11][11] = {0};    //reserve the path of minimum solution
int bracket[11]  = {0};    //store the number of bracket for each matrix,1:'(' ;    2:')'

void generate(int i, int j);    //get way to bracket arrangement
int main()
{
    int n;            //number of cases
    int p;            //row of matrix
    int q;            //column of matrix
    int count = 1;    //number of case
    int sum = 0;    //store value temporarily to short time cost

    while ((cin>>n) && (n > 0))    //get in n,when n==0 program ends
    {
        //input
        for (int i=0; i<n; i++)
        {
            cin>>p>>q;
            a[i] = p;
        }
        a[n] = q;
        //for special case N=1,2
        if (n == 1)
        {
            cout<<"Case "<<count++<<':'<<"A1"<<endl;
            continue;
        }
        if (n == 2)
        {
            cout<<"Case "<<count++<<':'<<"A1 x A2"<<endl;
            continue;
        }
        //for normal case N>2
            //initailize dp[][],way[][]
        for (int l=0; l<=n; l++)
        {
            for (int j=0; j<=n; j++)
            {
                dp[l][j] = 0;
                way[l][j] = 0;
            }
            bracket[l] = 0;
        }
            //dp
        for (int l=2; l<=n; l++)
            for (int i=0; i<=n-l; i++)
                for (int k=1; k<l; k++)
                {
                    sum = dp[k][i] + dp[l-k][i+k] + a[i] * a[i+k] * a[i+l];
                    if (dp[l][i] == 0)
                    {
                        dp[l][i] = sum;
                        way[i][i+l] = i + k;
                    }
                    else
                        if (sum < dp[l][i])
                        {
                            dp[l][i] = sum;
                            way[i][i+l] = i + k;
                        }
                }
       
        //generate the bracket arrangement
        generate(0,n);
        //cout
        cout<<"Case "<<count++<<": ";
        for (int i=1; i<n; i++)
        {
            if (bracket[i] > 0)
            {
                for (int j=0; j<bracket[i]; j++)
                    cout<<'(';
                cout<<'A'<<i;
            }
            else
            {
                cout<<'A'<<i;
                for (int j=0; j>bracket[i]; j--)
                    cout<<')';
            }
            cout<<" x ";
        }
        cout<<'A'<<n;
        for (int j=0; j>bracket[n]; j--)
            cout<<')';
        cout<<endl;
    }
    return 0;
}
void generate(int i, int j)    //get the arrangement of bracket,bracket[i] means how many brackets matrix Ai have
{
    if (j - i <= 1)    //no need of brackets
        return;
    bracket[i+1]++;    //
    bracket[j]--;    //add brackets
    if (j - i == 2)    //no need of recurse
        return;

    generate(i, way[i][j]);
    generate(way[i][j], j);
}