码迷,mamicode.com
首页 > 其他好文 > 详细

石子合并 区间dp模板

时间:2018-05-27 12:09:54      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:pair   +=   模板   swa   bsp   std   make   algo   区间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;
}

 

石子合并 区间dp模板

标签:pair   +=   模板   swa   bsp   std   make   algo   区间dp   

原文地址:https://www.cnblogs.com/SuuT/p/9095294.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!