首页 > 其他分享 >动态规划-区间DP

动态规划-区间DP

时间:2023-08-31 23:22:14浏览次数:30  
标签:状态 int 合并 区间 动态 石堆 DP

动态规划-区间DP

1. 区间DP的概念

    区间DP,顾名思义就是在一个个的区间上进行DP。

2. 区间DP问题-石子合并

    https://www.acwing.com/problem/content/284/

img
img

    我们还是从动态规划的两个角度来阐述该问题。
        1.  状态表示
            本问题,我们可以用二维状态来表示。即,f[i,j]。那么,该二维状态所表示的集合为:所有将第i堆石子到第j堆石子合并成一堆石子的合并方式的集合。属性为:所有合并方式的总代价的最小值。
        2.  状态计算
            我们如何将f[i,j]划分为一个个的子集呢?我们发现,无论是哪一种合并方式,最后一步都是将两堆合并成一堆。因此,我们可以按照最后一步的合并情况来进行划分。
            2.1 左边为1堆,右边为s-1堆所聚成的一堆。用区间表示:左边:[i,i],右边:[i+1,j]
            2.2 左边为2堆聚成的一堆,右边为s-2堆所聚成的一堆。左边:[i,i+1],右边:[i+2,j]
            ...
            2.s-1 左边为s-1堆聚成的一堆,右边为1堆。左边:[i,j-1],右边:[j,j]。
            在上述子集中,s代表从i堆到j堆的石堆总数。即:s = j - i + 1;
        我们可以将上述的子集划分,归纳成一般情况:
            最后一步的合并情况:
                实际上就是[i,k]和[k+1,j]两个区间进行合并。其中,k从i~j-1
    根据上述的情况,我们可以发现:在最后一步的合并情况中,都是将两个石堆合并成一个石堆。因此,我们可以将每个合并情况中的合并步骤去掉(这样的话,不会影响最小值,因为最后一步的合并所花费的代价相等),然后再加上这个最后一步合并所花费的代价即可。
    因此,状态转移方程:
        f[i][j] = min(f[i,k] + f[k+1,j] + s[j] - s[i-1])
        其中,s[j] - s[i-1] 为最后一步合并所需要的代价(第i个石堆到第j个个石堆的质量之和)(通过前缀和算法来进行求解即可)。
              k从i~j-1。
    需要注意的就是:由于DP问题在计算某个状态时,该状态之前的状态都已经计算好了。因此,在区间DP中,我们在计算状态时,需要按照区间的长度来进行遍历。因为在状态计算的时候,都是将该区间的子区间进行合并。因此,我们需要按照区间长度从小到大来进行遍历。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 310;

int s[N];

int f[N][N];

int n;


int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&s[i]);
    }
    //求解前缀和数组
    for(int i=1;i<=n;i++){
        s[i] += s[i-1];
    }
    //状态计算
    //按照区间长度从小到大遍历
    //先计算区间长度小的区间状态,再计算大的
    //这样的话,就可以保证题目正确
    //len=1的时候,只有一个石堆,不需要代价。
    for(int len=2;len<=n;len++){
        //遍历区间
        //假设,i为左端点,右端点为x,则:len = x - i + 1 => x = len + i - 1;
        for(int i=1; len + i - 1 <=n;i++){
            int l = i;
            int r = len + i - 1;
            f[l][r] = 0x3f3f3f3f;
            //遍历最后一步的划分情况
            for(int k=l;k<r;k++){
                f[l][r] = min(f[l][r],f[l][k] + f[k+1][r] + s[r] - s[l-1]);
            }
        }
    }
    printf("%d",f[1][n]);
    return 0;
}
    作者:gao79138
    链接:https://www.acwing.com/
    来源:本博客中的截图、代码模板及题目地址均来自于Acwing。其余内容均为作者原创。
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:状态,int,合并,区间,动态,石堆,DP
From: https://www.cnblogs.com/gao79135/p/17644101.html

相关文章

  • Java - ThreadPoolExecutor线程池分析
    Java- ThreadPoolExecutor源码分析 1.为什么要自定义线程池首先ThreadPoolExecutor中,一共提供了7个参数,每个参数都是非常核心的属性,在线程池去执行任务时,每个参数都有决定性的作用。但是如果直接采用JDK提供的方式去构建,可见设置的核心参数最多就两个,这样就会导致对线程池......
  • UOJ-783 新年的双区间操作
    题意给定一个序列\(a\),给一个操作序列\(m\),每个操作形如\((l_i,r_i,x_i,l'_i,r'_i,y_i)\),表示如果区间\([l_i,r_i]\)最大值大于等于\(x_i\)则将区间\([l'_i,r'_i]\)对\(y_i\)取\(\max\)。现在进行\(q\)次修改,每次先将\(a_p\)修改为\(v\)(这个修改是累积......
  • 长回文子串-动态规划解法
    题目:​给你一个字符串s,找到s中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。示例1:输入:s="babad"输出:"bab"解释:"aba"同样是符合题意的答案。​Golang代码示例​​逻辑视频讲解funclongestPalindrome(sstring)string{ /......
  • baomidou动态数据库@DS
     全链路不能使用@TransactionalpublicinterfaceXXXBasicMapper{@DS("operating")List<XXXBasicVo>findBasicList(XXXBasicPageDtodto);@Service@DS("operating")publicclassXXXXXXBasicServiceImpl2implementsIXXXBasicService......
  • 【HarmonyOS】一文教你如何使用低代码平台网格布局动态加载数据
    【关键字】低代码平台、AGC、API6、网格布局、数据模型 【写在前面】正式开工之前,先来说一下今天要实现的内容,今天会实现一个网格布局的展示,我会创建一个数据模型,然后网格列表的数据从数据模型中获取,从而实现一个动态展示的效果。在实现之前,先来简单说一下什么是数据模型?在......
  • 动态数组指针应用
    TypeTMyArr=arrayofarrayofarrayofInteger;Pint=^TMyArr;varPArr:Pint;i,j,k,ic,jc,kc:Integer;beginic:=2;jc:=3;kc:=4;New(PArr);SetLength(PArr^,ic,jc,kc);fori:=0toic-1doforj:=0tojc-1......
  • 状压DP总结
    动态规划-状压类-总结状压类的题,一般都需要用到二进制的性质。(用到组合数概率也不小)母题2:考虑用二进制表示摆放方式,然后使用位运算判断攻击。变式有一位很小,状压,状态类似于母题。变式2有交换操作,所以与逆序对相关,然后数学讨论一下,再状压。变式3考虑用集合、余数表示,注意......
  • Educational Codeforces Round 148 (Rated for Div. 2)E. Combinatorics Problem(组合
    题目链接:https://codeforces.com/contest/1832/problem/E 题意:  当然这是化简后的题意,原题面和这个差距还是有点大的; 分析: 因为组合数有公式:  所以:   嗯,然后就没有了; 时间复杂度:O(n*k); 代码: #include<bits/stdc++.h>#defineintlonglong......
  • PyTorch多卡分布式训练DDP单机多卡
    前言因为课题组发的卡还没有下来,先向导师问了实验室的两张卡借用。之前都是单卡训练模型,正好在这个机会实践以下单机多卡训练模型的方法。关于DDP网上有很多资料,但都比较零碎(有些博客的代码甚至没办法run),Pytorch给出的官方文档看起来也比较吃力。因此这篇文章的主要目的是......
  • 使Windows11支持同时多个用户远程桌面连接(RDP)
    参考:https://www.wyr.me/post/701一、配置远程桌面服务更改限制连接的数量将用户限制到单独的远程桌面服务会话(可选)二、为termsrv.dll增加修改权限C:\Windows\System32\termsrv.dll详情请参考:https://www.wyr.me/post/701三、停止RemoteDesktopServices服务打开......