• SDNU 1048.石子合并2(区间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<bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define eps 1e-9
    #define pi acos(-1)
    
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int maxn = 1000 + 8;
    
    int n, a[maxn], sum[maxn], dp[maxn][maxn], mi;
    
    int main()
    {
        std::ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        cin >> n;
        sum[0] = 0;
        for(int i = 1; i <= n; i++)
        {
            cin >> a[i];
            sum[i] += a[i] + sum[i - 1];
        }
        for(int len = 1; len <= n; len++)
        {
            for(int i = 1; i <= n; i++)
            {
                int en = (i + len) % n == 0 ? n : (i + len) % n;
                int tmp;
                if(i + len <= n)
                    tmp = sum[i + len] - sum[i - 1];
                else
                    tmp = sum[n] - sum[i - 1] + sum[(i + len) % n];
                dp[i][en] = inf;
                for(int k = 0; k < len; k++)
                    dp[i][en] = min(dp[i][en], dp[i][(i + k) % n == 0 ? n : (i + k) % n] + dp[(i + k + 1) % n == 0 ? n : (i + k + 1) % n][en] + tmp);
            }
        }
        mi = dp[1][n];
        for(int i = 2; i <= n; i++)
            if(mi > dp[i][i - 1])
                mi = dp[i][i - 1];
        cout << mi <<'
    ';
        return 0;
    }
  • 相关阅读:
    Cookie
    laydate
    layer
    字符流
    java虚拟机学习(四)--垃圾收集算法
    java虚拟机学习(三)
    java虚拟机学习(二)
    java虚拟机学习(一)
    Mybatis学习(一)
    mysql数据库面试总结(一)
  • 原文地址:https://www.cnblogs.com/RootVount/p/11480394.html
Copyright © 2020-2023  润新知