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

区间DP

时间:2019-03-04 09:40:45      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:就是   mem   ima   http   jpg   eof   alt   题解   images   

技术图片

题面

有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。

输入:

有多组测试数据,输入到文件结束。 每组测试数据第一行有一个整数n,表示有n堆石子。 接下来的一行有n(0< n? <200)个数,分别表示这n堆石子的数目,用空格隔开

输出:

输出总代价的最小值,占单独的一行

样例输入:

3

1 2 3

7

13 7 8 16 21 4 18

样例输出

9

239

题解

若最初的第L堆石子和第R堆石子被合并在一起,则说明L~R之间的每堆石子也已经被合并,这样L和R才有可能相邻。因此,在任意时刻,任意一堆石子均可以用一个闭区间[L,R]来描述,表示这堆石子是由最初的第L~R堆石子合并而成,其重量为\(\sum_{i=L}^RA_i\)。另外一定存在一个整数k(L<=k<R),在这堆石子形成之前,先有第L~K堆石子合并成一堆,第K+1~R堆石子被合并成一堆,然后这两堆石子才合并而成。

dp[i][j]:以第i个为起点,第j个为终点,所需要的最小花费

sum[i]:第1个为起点,第i个为终点的,区间和

首先把sum算出来,然后我们进行合并

举个例子来说:

有4个石头,每一个的价值分别是 1 2 3 4,他们的对应下标也是1 2 3 4,现在要求出dp[1][4]的值,也就是把这些石头合并成一堆,所需要的最小花费

那么首先 :? dp[1][1]=dp[2][2]=dp[3][3]=dp[4][4]=0

当间隔为1时,我们很容易知道:? dp[1][2]=3,dp[2][3]=5,dp[3][4]=7

当间隔为2时:
dp[1][3]=min(dp[1][1]+dp[2][3],dp[1][2]+dp[3][3])+sum(1,3)=min(5,3)+6=9

dp[2][4]=min(dp[2][2]+dp[3][4],dp[2][3]+dp[4][4])+sum(2,4)=min(7,5)+9=14

当间隔为3时:
dp[1][4]=min(dp[1][1]+dp[2][4],dp[1][2]+dp[3][4],dp[1][3]+dp[4][4])+sum(1,4)
=min(14,10,9)+10=9+10=19

经过这一个模拟的过程,我们应该已经知道了区间DP的含义,依靠一个一个小区间来逐渐推导出大区间。

所以我们的关键代码为:

for(int k=i; k<j; k++)
    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);

AC代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 210;
int a[maxn];
int sum[maxn];
int dp[maxn][maxn];
int main(void)
{
    int n;
    cin>>n;
    memset(dp,0x3f,sizeof(dp));
    for(int i = 1; i <= n; i++)
    {
        cin>>a[i];
        dp[i][i] = 0;
        sum[i] += sum[i-1]+a[i];
    }

    for(int len = 2; len <= n; len++)      // 阶段 
    {
        for(int l = 1; l <= n-len+1; l++)  //左端点 
        {
            int r = l+len-1;              //右端点
            for(int k = l; k < r; k++)   //决策 
            {
                dp[l][r] = min(dp[l][r],dp[l][k]+dp[k+1][r]);
            } 
            dp[l][r] += sum[r]-sum[l-1];
        }
    }
    cout<<dp[1][n]<<endl; 
    return 0;
} 

区间DP

标签:就是   mem   ima   http   jpg   eof   alt   题解   images   

原文地址:https://www.cnblogs.com/AC-AC/p/10468837.html

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