首页 > 其他分享 >动态规划做题记录

动态规划做题记录

时间:2024-11-01 12:41:49浏览次数:1  
标签:10 ch 记录 int void while include 规划 动态

个人做完题目后的总结。

所有记录仅代表个人,如果您是神犇觉得我太菜/题目是 sb 题/马蜂奇特请亲喷。

树形 dp

P9437 『XYGOI round1』一棵树

首先写了 \(O(n^2)\) 的暴力,记录 \(a_i\) 的位数可以过 \(20\text{pts}\)

点击查看代码
#ifdef ONLINE_JUDGE
#else
#define FRZ_29
#endif

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
typedef long long LL;

using namespace std;

void RD() {}
template<typename T, typename... U> void RD(T &x, U&... arg) {
    x = 0; int f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    x *= f; RD(arg...);
}

void WT() {}
template<typename T> void WT(T &x) {
    if (x < 0) { putchar('-'); x = -x; }; 
    if (x > 9) WT(x / 10);
    putchar(x % 10 + '0');
}

const int mod = 998244353;
const int N = 1e6 + 5;

#define PRINT(x) cout << #x << " = " << x << "\n"
#define LF(i, __l, __r) for (int i = __l; i <= __r; i++)
#define RF(i, __r, __l) for (int i = __r; i >= __l; i--)

LL head[N], ver[N << 1], Next[N << 1], tot = 1;
LL n, a[N], ans, dis[N], dig[N];

void add(int u, int v) {
    Next[++tot] = head[u]; ver[head[u] = tot] = v;
}

void dfs(int u, int _f) {
    for (int i = head[u]; i; i = Next[i]) {
        int v = ver[i]; if (v == _f) continue; 
        int x = a[v]; dis[v] = dis[u];
        if (dig[v]) { dis[v] = 1LL * dis[v] * dig[v] % mod; }
        else if (x == 0) { dig[v] = 10; dis[v] = dis[v] * 10 % mod; }
        else while (x) { (dig[v] = dig[v] == 0 ? 10 : dig[v] * 10) %= mod; dis[v] = dis[v] * 10 % mod; x /= 10; }
        dis[v] = (dis[v] + a[v]) % mod;
        dfs(v, u);
    }

    (ans += dis[u]) %= mod;
}

int main() {
#ifdef FRZ_29
    freopen("z_example.in", "r", stdin);
    freopen("z_example.out", "w", stdout);
#endif

    RD(n);
    LF(i, 1, n) RD(a[i]);
    LF(i, 2, n) {
        int fa; RD(fa); add(fa, i), add(i, fa);
    }

    LF(i, 1, n) {
        dis[i] = a[i]; dfs(i, 0);
        // LF(i, 1, n) printf("dis[%d] = %d\n", i, dis[i]);
    }
    printf("%lld\n", ans);
    return 0;
}

// START:2024/10/30 21:06:11;

然后考虑特殊性质 1。

设 \(T(i, j)\) 为 \(i \rightarrow j\) 经过所有数的位数和(不包括 \(i\))。

想到 \(i \rightarrow j\) 的贡献中 \(a_i\) 的贡献为 \(10^{T(i, j)} \times a_i\)。

遂想到换根转移 \(f_u = \sum_{i \in [1, n]} ^ {i \not= u} T(u, i)\) 来计算每个点对答案的贡献。

但经过实操发现困难,于是向题解求助。

发现只要改变成求其他点到该点的贡献就好处理了。

点击查看代码
#ifdef ONLINE_JUDGE
#else
#define FRZ_29
#endif

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
typedef long long LL;

using namespace std;

void RD() {}
template<typename T, typename... U> void RD(T &x, U&... arg) {
    x = 0; int f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
    x *= f; RD(arg...);
}

void WT() {}
template<typename T> void WT(T &x) {
    if (x < 0) { putchar('-'); x = -x; }; 
    if (x > 9) WT(x / 10);
    putchar(x % 10 + '0');
}

const int N = 1e6 + 5;
const int mod = 998244353;

#define PRINT(x) cout << #x << " = " << x << "\n"
#define LF(i, __l, __r) for (int i = __l; i <= __r; i++)
#define RF(i, __r, __l) for (int i = __r; i >= __l; i--)

int lg(int x) {
    int t = 0;
    if (x == 0) return 1;
    else while (x) t++, x /= 10; 
    return t;
}

int head[N], ver[N << 1], Next[N << 1], tot = 1;
int n, a[N], sz[N], dig[N];
LL f[N], g[N], pw[N], sum[N], ans;

void add(int u, int v) {
    Next[++tot] = head[u];
    ver[head[u] = tot] = v;
}

void dfs1(int u, int _f) {
    dig[u] = lg(a[u]), sz[u] = 1;
    for (int i = head[u]; i; i = Next[i]) {
        int v = ver[i]; if (v == _f) continue;
        dfs1(v, u); sz[u] += sz[v];
        (sum[u] += f[v]) %= mod;
        (f[u] += f[v] * pw[dig[u]] % mod + 1LL * sz[v] * a[u]) %= mod;
    }

    (f[u] += a[u]) %= mod;
}

void dfs2(int u, int _f) {
    for (int i = head[u]; i; i = Next[i]) {
        int v = ver[i]; if (v == _f) continue;
        g[v] = ((g[u] + (sum[u] + mod - f[v]) % mod) % mod * pw[dig[u]] + 1LL * (n - sz[v]) * a[u] % mod) % mod;
        (ans += (g[v] + sum[v]) % mod * pw[dig[v]] + 1LL * n * a[v] % mod) %= mod;
        dfs2(v, u);
    }
}

int main() {
#ifdef FRZ_29
    freopen("z_example.in", "r", stdin);
    freopen("z_example.out", "w", stdout);
#endif

    pw[1] = 10;
    LF(i, 2, 9) pw[i] = pw[i - 1] * 10 % mod;
    RD(n);
    LF(i, 1, n) RD(a[i]);
    LF(i, 2, n) {
        int fa; RD(fa);
        add(fa, i), add(i, fa);
    }

    dfs1(1, 0);
    ans += f[1];
    dfs2(1, 0);
    printf("%lld\n", ans);
    return 0;
}

// START:2024/10/31 17:47:59;

似乎一条路走不通改换条路走呢。

无边落木萧萧下,不尽长江滚滚来。

标签:10,ch,记录,int,void,while,include,规划,动态
From: https://www.cnblogs.com/FRZ29/p/18519920

相关文章

  • 0-petalinux 问题记录-VFS: Cannot open root device fs or unknown-block(0,0): erro
    0-petalinux问题记录-VFS:Cannotopenrootdevicefsorunknown-block(0,0):error-6这个问题是对SD卡分区之后,ext4分区写入一个文件系统之后的现象,不能正常启动,通过log可以看出来是能找到sd卡的分区,提示需要增加引导,可是在镜像构建的时候UBoot那里面已经设置过了,参数没......
  • 0-petalinux 问题记录-VFS: Cannot open root device fs or unknown-block(0,0): erro
    0-petalinux问题记录-VFS:Cannotopenrootdevicefsorunknown-block(0,0):error-6这个问题是对SD卡分区之后,ext4分区写入一个文件系统之后的现象,不能正常启动,通过log可以看出来是能找到sd卡的分区,提示需要增加引导,可是在镜像构建的时候UBoot那里面已经设置过了,参数没......
  • Zookeeper 学习的一些资料和实操遇到的问题的记录
    主要参考地址:https://www.cnblogs.com/leeSmall/p/9563547.htmlzookeeper安装问题:https://blog.csdn.net/peng2hui1314/article/details/107255142/注意配置文件多余空格问题,会导致启动失败,认真检查注意不要下载错了版本       标准版本(apache-zookeep......
  • Fusion Studio 19.0.3 (macOS, Windows) - 视觉特效、3D、VR 及动态图形解决方案
    FusionStudio19.0.3(macOS,Windows)-视觉特效、3D、VR及动态图形解决方案BlackmagicDesignFusionStudio请访问原文链接:https://sysin.org/blog/blackmagic-design-fusion/查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgFusion19登场卓越领先的视觉特......
  • 嵌入式相关记录
    最近需要参与嵌入式开发,因此开始学习嵌入式相关知识,此处记录一些专业名词,并作以解释。 单片机(MCU)MCU是微控制器单元(MicrocontrollerUnit)的简称,是一种集成了微处理器核心、存储器和输入/输出接口等功能模块的单芯片微型计算机系统。MCU是一种集成电路芯片,它将中央处理器CPU、......
  • C语言用GNU源码编译建构系统工具(GNU BUILD SYSTEM)编译创建动态库
    C语言用GNU源码编译建构系统工具(GNUBUILDSYSTEM)编译创建动态库首先看一下这篇博文:C语言数据结构之顺序结构(Sequence)此次目的是将sequence.c改造一下,创建为一个动态链接库同时打包一个可发布的源码包,包括源码、头文件、测试文件!创建工作目录工作目录libmg(mg即muggles,一......
  • 动态规划 01背包(算法)
    现有四个物品,小偷的背包容量为8,怎么可以偷得价值较多的物品如:物品编号:1   2   3   4 物品容量:2   3   4   5物品价值:3   4   5   8记f(k,w),当背包容量为w,可以偷k件物品,所能偷到的最大价值以f(4,8)为列,记录每......
  • 论文速读记录 - 202410
    坚持看论文不容易啊,十月也是多事之秋。看的论文有点少,也有点散,还是要专注一些具体的方向,梳理脉络,整理方案,才是看论文找解决方案的正确思路。以后的每篇论文解读的后面,会附带一点个人看法/评论,如有冒犯还请见谅。目录:LATECHUNKING:CONTEXTUALCHUNKEMBEDDINGSUSINGLONG-C......
  • 动态规划<二>路径问题
    目录路径问题1.第一题2.第二题3.第三题 4.第四题 5.第五题6.第六题路径问题1.第一题LeetCode<62>不同路径画图分析动态规划解题的几步1.确定状态表示根据经验+题目要求dp[i][j]表示走到[i,j]位置时的不同路径数2.状态转移方程以当前[i,j]位置状态的最......
  • CSP-S 2022 - 模拟赛记录
    PrefaceT1调的太久了,应当先打够部分分就切题的,全分思维难度不高,代码难度超高。可能是出题人知道把最简单题放T2有点过于恶心,所以后两道题的部分分都很好打,给的分也很多,一共\(55\)分可以轻松到手。就是第二题卡了一个unsignedlonglong,有点莫名其妙,而且T1放模拟也是头......