zoukankan      html  css  js  c++  java
  • 石子合并(区间dp典型例题)

    Description

    有n堆石子排成一行,每次选择相邻的两堆石子,将其合并为一堆,记录该次合并的得分为两堆石子个数之和。已知每堆石子的石子个数,求当所有石子合并为一堆时,最小的总得分。

    Input

    第一行一个整数n(1 <= n <= 200),表示石子堆数; 第二行n个整数a(1 <= a <= 100),表示每堆石子的个数。

    Output

    一个整数,表示最小总得分。

    Sample Input

    5
    7 6 5 7 100

    Sample Output

    175

    Source

    Unknown
    代码:
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<set>
    #include<vector>
    #include<map>
    #include<cmath>
    #define Inf 0x3f3f3f3f
    const int maxn=1e5+5;
    typedef long long ll;
    using namespace std;
    int a[205],g[205][205],sum[205];
    int dp[205][205];
    int main()
    {
       int n;
       cin>>n;
       
       for(int t=1;t<=n;t++)
       {
           scanf("%d",&a[t]);
       }
       for(int t=1;t<=n;t++)
       {
           sum[t]=sum[t-1]+a[t]; 
       }
       memset(dp,Inf,sizeof(dp));
       for(int t=1;t<=n;t++)
       {
           for(int j=t;j<=n;j++)
           {
               g[t][j]=sum[j]-sum[t-1];
        }
       }
       for(int t=1;t<=n;t++)
       {
           dp[t][t]=0;
       }
       for(int l=1;l<n;l++)
       {
           for(int j=1;j+l<=n;j++)
           {
               int r=j+l;
               for(int k=j;k<r;k++)
               {
                   dp[j][r]=min(dp[j][r],dp[j][k]+dp[k+1][r]+g[j][k]+g[k+1][r]); 
            }
        }
       }
       cout<<dp[1][n]<<endl;
       return 0;
    }
  • 相关阅读:
    Bzoj 1036: [ZJOI2008]树的统计Count
    cogs 1176. [郑州101中学] 月考
    cogs 610. 数对的个数
    Codevs 1247 排排站
    洛谷P1962 斐波那契数列
    Codevs 1051 接龙游戏
    2012 Noip提高组 Day2
    2012 Noip提高组 Day1
    poj1061 青蛙的约会
    一些常用的模板
  • 原文地址:https://www.cnblogs.com/Staceyacm/p/11228382.html
Copyright © 2011-2022 走看看