zoukankan      html  css  js  c++  java
  • [swustoj 404] 最小代价树

    最小代价树(0404)

    问题描述

    以下方法称为最小代价的字母树:给定一正整数序列,例如:4,1,2,3,在不改变数的位置的条件下把它们相加,并且用括号来标记每一次加法所得到的和。 
    例如:((4+1)+ (2+3))=((5)+(5))=10。除去原数不4,1,2,3之外,其余都为中间结果,如5,5,10,将中间结果相加,得到:5+5+10= 20,那么数20称为此数列的一个代价,若得到另一种算法:(4+((1+2)+3))=(4+((3)+3))=(4+(6))=10,数列的另一个代价为:3+6+10=19。若给出N个数,可加N-1对括号,求出此数列的最小代价。 
    注:结果范围不超出longint.

    输入

    第一行为数N(1≤N≤200),第二行为N个正整数,整数之间用空格隔开。

    输出

    输出仅一行,即为最少代价值。

    样例输入

    4
    4 1 2 3

    样例输出

    19

    简单区间DP、

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    #define ll long long
    #define MOD 1000000007
    #define INF 0x3f3f3f3f
    #define N 310
    
    int a[N];
    int sum[N];
    int dp[N][N]; //dp[i][j]表示区间i,j的最小代价
    
    int main()
    {
        int n;
        int i,j,k,len;
        while(scanf("%d",&n)!=EOF)
        {
            memset(dp,INF,sizeof(dp));
            for(i=1;i<=n;i++){
                scanf("%d",&a[i]);
                sum[i]=sum[i-1]+a[i];
                dp[i][i]=0;
            }
            for(len=1;len<=n;len++){
                for(i=1;i<=n-len+1;i++){
                    j=i+len-1;
                    for(k=i;k<j;k++){
                        dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
                    }
                }
            }
            printf("%d
    ",dp[1][n]);
        }
        return 0;
    }
  • 相关阅读:
    转 c#性能优化秘密
    转 the best for wcf client
    迁移到简书通知
    docker初体验
    PyQT 单词弹幕桌面生成!
    Python 常见排序查找算法-二分法,归并,冒泡,插入
    Python 将小姐姐画在Excel上
    TensorFlow基于神经网络实现井字棋
    TensorFlow(八) TensorFlow图像识别(KNN)
    TensorFlow(七) 地址匹配
  • 原文地址:https://www.cnblogs.com/hate13/p/4572446.html
Copyright © 2011-2022 走看看