zoukankan      html  css  js  c++  java
  • 石子合并 区间dp模板

    题意:中文题

    Description

    在操场上沿一直线排列着 n堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分。允许在第一次合并前对调一次相邻两堆石子的次序。

    计算在上述条件下将n堆石子合并成一堆的最小得分。

    Input

    输入数据共有二行,其中,第1行是石子堆数n≤100;
    第2行是顺序排列的各堆石子数(≤20),每两个数之间用空格分隔。

    Output

    输出合并的最小得分。

    Sample Input

    3 2 5 1

    Sample Output

    11

    Source

    NOI1995

     
    题解:区间dp,交换的处理
     
     
    代码
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
    #define per(i,j,k) for(int i = (int)j;i >= (int)k;i --)
    #define mmm(a,b) memset(a,b,sizeof(a))
    #define pb push_back
    #define mp make_pair;
    const int maxn=1e2+5;
    int n;
    int a[maxn];
    int dp[maxn][maxn];
    int main() {
        cin >> n;
        //fill(dp, dp + maxn*maxn, 1e9);
        int ans = 1e9;
        rep(i, 1, n)cin >> a[i], dp[i][i] = 0;
        rep(i, 1, n-1) {
            swap(a[i], a[i + 1]);
            rep(len, 2, n)//len
                rep(i, 1, n - len + 1)//begin
            {
                dp[i][i + len - 1] = 1e9;
                int sum = 0; rep(j, i, i + len - 1)sum += a[j];
                rep(k, i, len + i - 2)//k
                {
                    dp[i][i + len - 1] = min(dp[i][i + len - 1], dp[i][k] + dp[k + 1][i + len - 1] + sum);
                }
            }
            ans=min(ans,dp[1][n]);
            swap(a[i], a[i + 1]);
        }
        cout << ans;
        cin >> n;
    }
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    Linux下安装Readis
    windows下的Redis安装:
    解决@ResponseBody不能和 <mvc:annotation-driven>同时使用的问题
    dom4j操作XML
    Ajax优缺点
    来一打前端博客压压惊
    tinypng upload一键压缩上传工具,告别人肉
    手把手教你撸一个简易的 webpack
    前端路由简介以及vue-router实现原理
    JS 数据类型、赋值、深拷贝和浅拷贝
  • 原文地址:https://www.cnblogs.com/SuuT/p/9095294.html
Copyright © 2011-2022 走看看