首页 > 其他分享 >区间dp

区间dp

时间:2024-02-17 18:44:06浏览次数:20  
标签:int 样例 合并 区间 最优 左右两个 dp

合并类动态规划

  • 合并:意思就是将两个或多个部分进行整合,当然也可以反过来,也就是是将一个问题进行分解成两个或多个部分。
  • 特征:能将问题分解成为两两合并的形式
  • 求解:对整个问题设最优值,枚举合并点,将问题分解成为左右两个部分,最后将左右两个部分的最优值进行合并得到原问题的最优值。有点类似分治算法的解题思想。
  • 典型试题:整数划分,凸多边形划分、石子合并、多边形合并、能量项链等。
  • 主要思路:将整区间分成所有可以分成的小区间,依次遍历求最小最大值。

普遍模板:

for(int len=1; len<=n; len++){ //依次遍历区间长度
        for(int i=1; i+len-1<=n; i++){
            int j = i + len - 1; //i为区间起点,j为终点
            for(int k=i; k<j; k++){
                f[i][j] = min/max(f[i][j], f[i][k]+f[k+1][j]+a[k]);
            }
        }
    }

例题

样例输入:

4
4 5 9 4

样例输出:

44
54

解:

  #include<bits/stdc++.h>
using namespace std;

const int N = 110;

int n;
int f[N][N], g[N][N];
int a[N], s[N];

int main(){

    scanf("%d",&n);
    for(int i=1; i<=n; i++){
        scanf("%d", &a[i]);
        s[i] = s[i-1] + a[i]; //前缀和预处理
    }

    memset(f, 0x3f, sizeof(f));
    
    for(int i=1; i<=n; i++) f[i][i] = 0;

    for(int len=1; len<=n; len++){
        for(int i=1; i+len-1<=n; i++){
            int j = i + len - 1;
            for(int k=i; k<j; k++){
                f[i][j] = min(f[i][j], f[i][k]+f[k+1][j]+s[j]-s[i-1]);
                g[i][j] = max(g[i][j], g[i][k]+g[k+1][j]+s[j]-s[i-1]);
            }
        }
    }
    printf("%d\n", f[1][n]);
    printf("%d\n", g[1][n]);

    return 0;
}

标签:int,样例,合并,区间,最优,左右两个,dp
From: https://www.cnblogs.com/zyzAqr/p/18018214

相关文章

  • 区间dp
    1.合并石子(1)排成一列的石子这个与合并果子唯一的不同就是只能合并相邻的石子,所以贪不得(怎么所有类型的动规要先上来搞贪心,有点diss贪心的感觉)f[i][j]表示i到j间合并的最大/最小得分;核心for(intlen=2;len<=n;len++){//表示长度2到len时的最大 for(inti=1;i+len-1<=n;i++)......
  • 背包dp
    01背包描述:有n个物品,每个物品只有一件,第i个物品体积为vi,价格为ci。现在有一个体积为V的背包,请你从n件物品里选出若干件放进背包里,使得背包里的物品价值最大。思路:01背包的特点是:每种物品只有一件,可以选择放或不放。我们可以根据此特点进行动态规划(DP),设f[i][j]表示前i件物品放......
  • 动态规划-DP 完整版
    动态规划学完了五大基础dp做个简单总结dp特征动态规划问题首要是找到做题的目的是求最大/小值还是其他;其二要确定问题的状态转移方程这是关键;第三为dp数组找到边界、最后检查是否需要结合其他相关知识如树dfs等;别忘了检查多测输入数组变量置零等易错点。......
  • 线性dp
    线性动态规划:不用多说,主要应用于求上升子序列,下降子序列等直接看例题:样例输入:13791638243718441921226315样例输出:max=879161819212263解:#include<bits/stdc++.h>usingnamespacestd;constintMAX=1050;intn,ans;intf[MAX],......
  • DP总结
    DP总结1.背包DP-0/1背包-完全背包-多重背包-分组背包-依赖背包-二维背包-树形背包DP0/1背包朴素版点击查看代码#include<bits/stdc++.h>usingnamespacestd;constintmaxn=1010;//f[i][j]表示前i个物品,体积不超过j时的最大价值//不选第i个物品时,f[i][j]......
  • 回顾复习之线性DP
    概念具有线性阶段划分的动态规划算法叫作线性动态规划(简称线性DP)。若状态包含多个维度,则每个维度都是线性划分的阶段,也属于线性DP,如下图所示:如果状态包含多个维度,但是每个维度上都是线性划分的阶段,也属于线性DP。比如背包问题、区间DP、数位DP等都属于线性DP。例题求最......
  • 动态规划--一维dp和二维dp
    在解决背包问题时,使用一维动态规划数组和二维动态规划数组都是常见的方法,选择哪种方式取决于问题的特点和解法的需要。使用一维DP数组的情况:状态转移方程只涉及到上一行的元素:当状态转移方程只涉及到上一行的元素时,可以使用一维DP数组。这样能够降低空间复杂度,使算法更为简......
  • DP总结
    DP(动态规划)简介动态规划是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。由于动态规划并不是某种具体的算法,而是一种解决特定问题的方法,因此它会出现在各式各样的数据结构中,与之相关的题目种类也更为繁杂。DP基础1.必要前提需要满足三个条件:最优子......
  • 树形dp
    树形dp模型:给定一颗有n个节点的树,任选一个节点为根节点,从而定义出每个节点的深度和每棵子树的根。基本思路:1.建树2.列出动态转移方程典型例题:没有上司的舞会#include<bits/stdc++.h>usingnamespacestd;intn,l,k,ans;vector<int>son[6600];intf[6600][2],v[6600],r......
  • 区间DP
    先看一下模板点击查看代码//f[i][j]表示从i到j区间的值for(intlen=2;len<=n;len++)//len表示区间长度{ for(inti=1;i+len-1<=n;i++)//关系一般为2<=i<=k<j<=n { intj=i+len-1;//j的求值,开始点+区间长度-1 for(intk=i;k<j;k++) { f[i][j]=min/max(状态转移......