首页 > 其他分享 >基础动态规划

基础动态规划

时间:2023-05-04 22:12:37浏览次数:34  
标签:include const min int 基础 cin times 动态 规划

P1880 [NOI1995] 石子合并 题解

区间DP。

首先将其复制一遍(因为是环)。

设 \(f[i][j]\) 表示将 \(i\) 到 \(j\) 段的石子合并需要的次数。

\[f[i][j] = 0(i = j) \]

\[f[i][j] = min(max)\{f[i][k] + f[k + 1][j] + \sum_{k = i }^{j}a[k](i \leq k < j)\} \]

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 210;

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

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i], a[i + n] = a[i];
    for (int i = 1; i <= n * 2; i++) s[i] = s[i - 1] + a[i];

    memset(f, 0x3f, sizeof(f));
    memset(g, 0xcf, sizeof(g));

    for (int len = 1; len <= n; len++) {
        for (int i = 1; i + len - 1 <= n * 2; i++) {
            int j = i + len - 1;
            if (len == 1) {
                f[i][j] = 0;
                g[i][j] = 0;
            }
            else {
                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]);
                }
            }
        }
    }
    int ans1 = 0x3f3f3f3f, ans2 = 0xcfcfcfcf;

    for (int i = 1; i <= n; i++) ans1 = min(ans1, f[i][i + n - 1]), ans2 = max(ans2, g[i][i + n - 1]);
    cout << ans1 << '\n' << ans2 << '\n';
    return 0;
}

P5020 [NOIP2018 提高组] 货币系统 题解

转化为完全背包即可。

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 25010, M = 110;

int n;
int f[N];
int a[M];

void solve() {
    int maxx = 0;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i], maxx = max(maxx, a[i]);
    memset(f, 0, sizeof(f));
    f[0] = 1;
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        int x = a[i];
        for (int j = x; j <= maxx; j++) {
            f[j] += f[j - x];
        }
    }
    for (int i = 1; i <= n; i++) if (f[a[i]] > 1) ans++;
    cout << n - ans << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;
    while (T--) solve();
    return 0;
}

P1941 [NOIP2014 提高组] 飞扬的小鸟 题解

我们先不管障碍物。

设 \(f[i][j]\) 表示来到点 \((i,j)\) 的最少点击屏幕数。

因为每秒要不上升 \(k\times x[i]\),要么下降 \(y[i]\)。

所以有:

\[f[i][j] = min(f[i - 1][j + y[i]], f[i - 1][j - k \times x[i]]) \]

这表示从上一秒转移过来,要不是从上一秒下降下来,那么上一秒就在 \(j + y[i]\),

要不是从上一秒上升上来,那么上一秒就在 \(j - k\times x[i]\)。

会 \(TLE\)。

下面进行优化:

首先看上升:

\(f[i][j] = min(f[i - 1][j - x[i]] + 1, f[i - 1][j - 2 \times x[i]] + 2, f[i - 1][j - 3 \times x[i]] + 3, \dots)\)
\(f[i][j - x[i]] = min(f[i - 1][j - 2 \times x[i]] + 1, f[i - 1][j - 3 \times x[i]] + 2, f[i - 1][j - 4 \times x[i]] + 3, \dots)\)

发现规律得:

\(f[i][j] = min(f[i - 1][j - x[i]] + 1, f[i][j - x[i]] + 1)\)。

下降直接处理即可,两个要分开处理!

细节:

  1. 初始状态:

\[f[0][j] = 0 \]

\[f[i][j] = \infty(i \not= 0) \]

  1. 要统计超出高度 \(m\) 的一些点。

  2. 遇到障碍,把相应的 \(f\) 值设为 \(\infty\)。

  3. \(M\) 一定要开到 \(2000\),因为 \(j + y[i]\) 可能达到 \(2000\)。

代码;

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 10010, M = 2010;

struct Node {
    int x, l, r;
}c[N];

int n, m, cnt;
int x[N], y[N];
int f[N][M];
int cur = 1;

int main () {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> n >> m >> cnt;
    for (int i = 1; i <= n; i++) cin >> x[i] >> y[i];
    for (int i = 1; i <= cnt; i++) cin >> c[i].x >> c[i].l >> c[i].r;
    sort(c + 1, c + cnt + 1, [](const Node& a, const Node& b){ return a.x < b.x; });

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

    for (int i = 1; i <= n; i++) {
        for (int j = x[i]; j <= m + x[i]; j++) {
            f[i][j] = min(f[i - 1][j - x[i]] + 1, f[i][j - x[i]] + 1);
        }
        for (int j = m + 1; j <= m + x[i]; j++) {
            f[i][m] = min(f[i][m], f[i][j]);
        }
        for (int j = 1; j <= m - y[i]; j++) {
            f[i][j] = min(f[i][j], f[i - 1][j + y[i]]);
        }
        if (c[cur].x == i) {
            int l = c[cur].l, r = c[cur].r;
            while (l >= 0) f[i][l] = 0x3f3f3f3f, l--;
            while (r <= m) f[i][r] = 0x3f3f3f3f, r++;
            int ans = 0x3f3f3f3f;
            for (int j = 0; j <= m; j++) ans = min(ans, f[i][j]);
            if (ans == 0x3f3f3f3f) {
                cout << 0 << '\n' << cur - 1 << '\n';
                exit(0);
            }
            cur++;
        }
    }
    int ans = 0x3f3f3f3f;
    for (int i = 0; i <= m; i++) ans = min(ans, f[n][i]);
    cout << 1 << '\n' << ans << '\n';
    return 0;
}

祝大家在WC-2023上玩的愉快。

标签:include,const,min,int,基础,cin,times,动态,规划
From: https://www.cnblogs.com/PlayWithCPP/p/17372694.html

相关文章

  • 20201306 Exp6 MSF应用基础
    一、实践内容二、实践原理三、实践过程1、一个主动攻击实践ms08_067_netapims17_0102、一个针对浏览器的攻击ms14_064ms17-0103、一个针对客户端的攻击AdobeWireshark4、成功应用一个辅助模块sniffer嗅探portscan端口扫描MSF使用nmap四、实践问题回答五、离实践......
  • js数据结构变化 table动态列展示
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=......
  • 矩阵基础知识
    文章目录1.矩阵的一些基础知识1.1矩阵只有乘法1.2向量有点乘(也是内积)和叉乘:1.3单位向量1.4正交矩阵1.5线性无关和线性相关的向量1.6矩阵的逆1.7对称矩阵1.7矩阵的秩(rank)1.8伴随矩阵1.9矩阵的零空间1.10矩阵的扩展基定理1.矩阵的一些基础知识1.1矩阵只有乘法1.2向量......
  • Exp6 MSF应用基础
    一、实验原理(1)MSF简介Metasploit是一个免费的、可下载的框架,通过它可以很容易地获取、开发并对计算机软件漏洞实施攻击。它本身附带数百个已知软件漏洞的专业级漏洞攻击工具。(2)程序特点这种可以扩展的模型将负载控制,编码器,无操作生成器和漏洞整合在一起,使MetasploitFramewo......
  • Exp6 MSF应用基础 20202211王宏韬
    目录1基础问题回答2实验总结与体会3离实践缺少什么4实践过程记录主动攻击实践针对浏览器攻击针对adobe客户端攻击应用辅助模块tcp端口扫描   1基础问题回答 exploit:利用发现的安全漏洞或配置弱点对靶机进行攻击,将payload发送给靶机。payload:植入靶机......
  • java基础-数组的定义,静动态初始化,数组元素的相关操作、数组的内存图
    一、什么是数组数组指的是一种容器,可以用来存储同种数据类型的多个值。数组容器在存储数据的时候,需要结合隐式转换考虑。例如:int类型的数组容器,只能存储byte、short、int类型的数据。(byte<short<int<long<float<double)例如:double类型的数组容器,可以存储byte、short、int、long......
  • 网络对抗实验六 MSF应用基础
    目录实践内容一、主动攻击实践二、针对浏览器的攻击三、针对客户端的攻击四、应用一个辅助模块问题回答一、基础问题回答1.用自己的话解释什么是exploit,payload,encode.二、实践总结与体会实践内容一、主动攻击实践关闭靶机防火墙打开445端口查看版本msfconsolesearchs......
  • 动态规划简介
    目录动态规划与分治法基本思想和步骤实现方法钢条切割问题递归方法动态规划子问题图典型题目参考文献动态规划与分治法动态规划(dynamicprogramming)与分治方法相似,都是通过组合子问题的解来求解原问题(在这里,“programming”指的是一种表格法,并非编写计算机程序)。分治方法将问题......
  • 卷积神经网络基础
     卷积神经网络是进行图像处理的基础神经网络模型,其包含卷积、池化、激活函数和展平四个主要部分。卷积是一种基本的信号处理操作,在图像处理中也得到广泛应用,基本原理是将一个输入的图像或信号与一个小的卷积核进行卷积运算,得到一个输出的特征图。如下图选取一个3x3的卷积核,对一......
  • Exp6 MSF应用基础 20201331黄文刚
    Exp6MSF应用基础一、实验原理(1)MSF简介Metasploit是一个免费的、可下载的框架,通过它可以很容易地获取、开发并对计算机软件漏洞实施攻击。它本身附带数百个已知软件漏洞的专业级漏洞攻击工具。(2)程序特点这种可以扩展的模型将负载控制,编码器,无操作生成器和漏洞整合在一起,使M......