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;
    }
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    Tabindex
    bootStrap下拉菜单 点击下拉列表某个元素,列表不隐藏
    ionic--分模块
    ionic--配置路由
    ionic —指令
    一个简单的Makefile的编写【用自己的话,解释清楚这些】
    使用ptrace向已运行进程中注入.so并执行相关函数
    StrictMode模式介绍
    adb server is out of date. killing...
    交叉编译lsof for android
  • 原文地址:https://www.cnblogs.com/SuuT/p/9095294.html
Copyright © 2011-2022 走看看