动态规划—区间DP(二)

简介: AcWing算法提高课内容,本文讲解 动态规划

加分二叉树

题目要求

题目描述:

image.png

输入格式:

第 1  行:一个整数 n ,为节点个数。

第 2  行:n  个用空格隔开的整数,为每个节点的分数(0 <  分数 < 100 )。

输出格式:

1 行:一个整数,为最高加分(结果不会超过int范围)。

第 2 行:n  个用空格隔开的整数,为该树的前序遍历。如果存在多种方案,则输出字典序最小的方案。

数据范围:

n<30

输入样例:

5
5 7 1 2 10

输出样例:

145
3 1 2 4 5

思路分析

image.png

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 35;
int n;
int w[N];
int f[N][N];  // 存储从 [i, j] 的最高分
int g[N][N];  // 存储从 [i, j] 的根节点
void print(int l, int r)
{
    if (l > r) return;
    cout << g[l][r] << ' ';
    print(l, g[l][r] - 1);   // 递归左子树
    print(g[l][r] + 1, r);   // 递归右子树
}
int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ ) cin >> w[i];
    for (int len = 1; len <= n; len ++ )
        for (int l = 1; l + len - 1 <= n; l ++ )
        {
            int r = l + len - 1;
            if (len == 1) f[l][r] = w[l], g[l][r] = l;
            else
                for (int k = l; k <= r; k ++ )
                {
                    int left = k == l ? 1 : f[l][k - 1];
                    int right = k == r ? 1 : f[k + 1][r];
                    int score = left * right + w[k];
                    if (f[l][r] < score)
                    {
                        f[l][r] = score;
                        g[l][r] = k;
                    }
                }
        }
    cout << f[1][n] << endl;
    print(1, n);     // 递归输出前序遍历
    return 0;
}

凸多边形的划分

题目要求

题目描述:

给定一个具有 N  个顶点的凸多边形,将顶点从 1  至 N 标号,每个顶点的权值都是一个正整数。

将这个凸多边形划分成 N − 2 个互不相交的三角形,对于每个三角形,其三个顶点的权值相乘都可得到一个权值乘积,试求所有三角形的顶点权值乘积之和至少为多少。

输入格式:

第一行包含整数 N ,表示顶点数量。

第二行包含 N  个整数,依次为顶点 1  至顶点 N  的权值。

输出格式:

输出仅一行,为所有三角形的顶点权值乘积之和的最小值。

数据范围:

N50,

数据保证所有顶点的权值都小于109

输入样例:

5
121 122 123 245 231

输出样例:

12214884

思路分析

image.png

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
const int N = 55;
int n;
int w[N];
vector<int> f[N][N];
bool cmp(vector<int> &a, vector<int> &b)
{
    if (a.size() != b.size()) return a.size() < b.size();
    for (int i = a.size() - 1; i >= 0; i -- )
        if (a[i] != b[i])
            return a[i] < b[i];
    return true;
}
vector<int> add(vector<int> a, vector<int> b)
{
    vector<int> c;
    int t = 0;
    for (int i = 0; i < a.size() || i < b.size(); i ++ )
    {
        if (i < a.size()) t += a[i];
        if (i < b.size()) t += b[i];
        c.push_back(t % 10);
        t /= 10;
    }
    while (t) c.push_back(t % 10), t /= 10;
    return c;
}
vector<int> mul(vector<int> a, LL b)
{
    vector<int> c;
    LL t = 0;
    for (int i = 0; i < a.size(); i ++ )
    {
        t += b * a[i];
        c.push_back(t % 10);
        t /= 10;
    }
    while (t) c.push_back(t % 10), t /= 10;
    return c;
}
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]);
    //区间DP
    //此处初始状态f[l][l+1] = 0 初始就是空vector,不用额外设置
    for (int len = 3; len <= n; len ++ )
    {
        for (int l = 1, r; (r = l + len - 1) <= n; l ++ )
        {
            //初始化初始状态
            for (int k = l + 1; k < r; ++ k)
            {
                //w_l * w_k * w_r
                auto new_val = mul(mul({w[l]}, w[k]), w[r]); // {w[l]}可以直接初始化为一个vector
                //f[l][k] + f[k][r] + cost
                new_val = add(add(new_val, f[l][k]), f[k][r]);
                //f[l][r] = min(f[l][r], f[l][k] + f[k][r] + w_sum)
                if (f[l][r].empty() || cmp(new_val, f[l][r])) f[l][r] = new_val;
            }
        }
    }
    //输出最终答案
    auto res = f[1][n];
    for (int i = res.size() - 1; i >= 0; i -- ) printf("%d", res[i]);
    puts("");
    return 0;
}




目录
相关文章
|
存储 SQL 算法
jvm性能调优 - 11J线上VM调优案例分享
jvm性能调优 - 11J线上VM调优案例分享
516 0
|
数据采集 Web App开发 存储
Selenium库编写爬虫详细案例
Selenium库编写爬虫详细案例
|
8月前
|
人工智能 JavaScript 前端开发
TVM虚拟机
TVM引擎是一款超微型、多功能的编程工具,支持多种语法(如Lisp、JavaScript等),拥有几百个实用函数。其核心优势包括快速加载执行、跨平台运行(Windows、Linux等)、源代码链接生成独立文件及嵌入宿主系统作为开发语言平台。此外,它具备动态脚本特性、符号单元运算、面向对象原型继承、函数式编程特点,以及C语言底层操作能力。TVM还支持弱类型数据处理、多态函数、内存垃圾自动回收、正则表达式文本处理和网络编程接口,广泛应用于分布计算、科学统计及人工智能等领域。
|
11月前
|
人工智能 Python
子曰-o1:网易有道开源国内首个分步式讲解推理模型,支持K12数学教学
子曰-o1是网易有道推出的国内首个分步式讲解推理模型,采用14B轻量级架构,专为消费级显卡设计,支持K12数学教学,提供精准的解题思路和答案。
560 1
子曰-o1:网易有道开源国内首个分步式讲解推理模型,支持K12数学教学
|
12月前
|
存储 JSON API
淘宝直播间弹幕API接口(taobao.item_video_barrage)
淘宝直播间弹幕 API(`taobao.item_video_barrage`)用于获取直播间的弹幕数据。通过指定直播间 ID 和模式参数(如 `start` 建立连接、`refresh` 获取弹幕),可以获取弹幕消息列表、直播间信息等。响应数据为 JSON 格式,包含状态码、直播间 ID、连接状态和弹幕详情。使用时需注意权限限制、接口稳定性和数据处理。
|
消息中间件 存储 机器学习/深度学习
推荐系统入门
前言我最近正在入门推荐系统,发现这是一个非常有意思的领域。推荐系统无处不在,现在几乎所有的网站和应用里最显眼的位置和重要的位置中都是推荐系统。电商类的软件,例如Amazon、京东、淘宝、拼多多;首页和商品页面附近都是推荐你购买新的商品;视频类软件,例如Youtube、Bilibili、爱奇艺,它们的首页和搜索页中也都在推荐你可能会喜欢的影片;游戏类软件,例如原神、王者荣耀,无时无刻都在推荐你它们的
720 1
|
机器学习/深度学习 编解码 数据可视化
转置卷积-清晰易懂
转置卷积(Transpose Convolution)是一种用于图像上采样的技术,常用于图像分割、生成对抗网络(GAN)等领域。与传统的上采样方法不同,转置卷积通过学习参数来实现更优的插值效果。本文介绍了转置卷积的背景、应用、与标准卷积的区别以及数学推导,帮助读者深入理解其原理和应用场景。
1161 1
|
关系型数据库 MySQL Linux
Docker安装mysql详细教程, mysqld: Can‘t read dir of ‘/etc/mysql/conf.d/‘(报错已解决)
Docker安装mysql详细教程, mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 2 - No such file or directory) 已解决
|
搜索推荐 Python
Python 冒泡排序:原理、使用场景与实现方法
本文主要介绍了Python 冒泡排序:原理、使用场景与实现方法
791 6
Python 冒泡排序:原理、使用场景与实现方法
|
算法 安全 Java
架构设计第十一讲:架构之高并发:限流
架构设计第十一讲:架构之高并发:限流
446 0