首页 > 其他分享 >dp学习笔记

dp学习笔记

时间:2024-08-06 20:28:48浏览次数:12  
标签:递归 sum pos 笔记 学习 limit ll dp

数位dp

对于数位上每个数的有约束的各类统计问题,可以考虑用数位 dp 解决。

通常使用记忆化递归实现(更通用),属于比较板子的 dp 了。

在进行记忆化递归时,通常需要考虑三个因素:前导零(有时需要考虑),值域边界限制(必定会有),题面要求限制。

例题

  1. P2602 [ZJOI2010] 数字计数

    版子题,枚举 \(0 \sim 9\) 的数字,按位统计即可。

    注意前导零对答案的影响。

    代码:

ll a,b,f[15][15][11][2],w[15],n;
ll calc(ll pos,ll k,ll lead,ll limit,ll sum){
	if(!lead&&!limit&&f[pos][sum][k][lead]!=-1) return f[pos][sum][k][lead];
	if(pos>n) return sum;
	ll res=0,up=9;
	if(limit) up=w[pos];
	for(int i=0;i<=up;i++){
		res+=calc(pos+1,k,(lead==1&&i==0)?1:0,(limit==1&&i==up)?1:0,sum+(i==k)-(i==k&&i==0&&lead));
	}
	if(!limit&&!lead) f[pos][sum][k][lead]=res;
	return res;
}
inline ll solve(ll k,ll now){
	memset(f,-1,sizeof(f));
	n=0;
	if(k==0) w[++n]=0;
	while(k){
		w[++n]=k%10,k/=10;
	}
	reverse(w+1,w+1+n);
	return calc(1,now,1,1,0);
}
  1. 恨7不成妻

    题目的三个条件易于约束,但是求平方和难以直接转移。

    考虑合并时的情况,从简单情况入手,前 \(pos-1\) 位已被固定(递归时进行统计),当前第 \(pos\) 位的数字为 \(i\),对构成数字本身的贡献为 \(a\),递归回来构成的数字为 \(b,c,\dots\)。

    那么递归时的答案计算应是 \((a+b)^2+(a+c)^2+\dots\),拆开来则是 \((a^2+2ab+b^2)+(a^2+2ac+c^2)+\dots\)。

    那么我们在递归时,就要维护三个量:可以构成的数字个数 \(k_1\)(计算多个 \(a_2\)),当前对数字本身的贡献 \(k_2\)(计算多个类似 \(2ab\) 对答案的贡献),以及当前的数字平方和 \(k_3\)(计算多个平方对答案贡献)。

    前两个量合并时直接相加即可,平方和合并便是 \(k_1a^2+2ak_2+k_3\)。

    代码:

struct node{
	ll sqsum,sum,cnt;
}f[25][10][10];
ll t,l,r,a[25],n,base[25],Base[25];
node calc(ll pos,ll sum,ll now,ll limit){
	if(!pos) return {0,0,(sum&&now)};
	if(!limit&&f[pos][sum][now].cnt!=-1) return f[pos][sum][now];
	node res={0,0,0},tmp;
	for(int i=0;i<=9;i++){
		if(limit&&a[pos]<i) break;
		if(i==7) continue;
		tmp=calc(pos-1,(sum+i)%7,(now+i*Base[pos-1]%7)%7,limit&&a[pos]==i);
		res.cnt=(res.cnt+tmp.cnt)%mod;
		res.sum=(res.sum+tmp.sum+i*tmp.cnt%mod*base[pos-1]%mod);
		res.sqsum=((res.sqsum+tmp.sqsum)%mod+2*tmp.sum%mod*i%mod*base[pos-1]%mod)%mod;
		res.sqsum=(res.sqsum+tmp.cnt*i%mod*base[pos-1]%mod*i%mod*base[pos-1]%mod)%mod;
	}
	if(!limit) f[pos][sum][now]=res;
	return res;
}
inline ll solve(ll x){
	memset(f,-1,sizeof(f));
	n=0;
	if(x==0) a[++n]=0;
	while(x){
		a[++n]=x%10,x/=10;
	}
	return calc(n,0,0,1).sqsum;
}

  1. P1831 杠杆数

    根据题目定义,可以得到一个性质:

    如果一个数是杠杆数,它的支点有且仅有一个。因为无论当前支点向左移还是向右移,左右的差必定单调递增,差必不为 \(0\)。

    所以,只需要枚举每一个作为支点的位置,进行 dp,状态为三维:位数,支点左右差值,支点位置。最后判断差是否为 \(0\) 即可。

标签:递归,sum,pos,笔记,学习,limit,ll,dp
From: https://www.cnblogs.com/dayz-break/p/18345930

相关文章

  • 动态规划之——背包DP(进阶篇)
    文章目录概要说明多重背包(朴素算法)模板例题思路code多重背包(二进制优化)模板例题思路code多重背包(队列优化)模板例题思路混合背包模板例题思路code1code2二维费用背包模板例题思路code概要说明本文讲多重背包、混合背包以及二维费用背包,至于其他背包问题后续......
  • C++笔记,类和对象(上)
    对于类的初步认识目录对于类的初步认识(1)类的定义(2)类的访问限定符及封装(3)类的作用域(4)类的实例化(5)类的对象大小的计算(6)类成员函数的this指针(1)类的定义classclassName{//类体,由成员函数和成员变量组成};//一定要注意后面的分号类体中内容称为类的成员:类......
  • C++ 学习预备知识
    1C++简介 1.1起源    C++与C语言一样,也是在贝尔实验室诞生的,名称C++来自C语言中的递增运算符++,该运算符将变量加1。这也表明,C++是C语言的扩充版本。    C++融合了3种不同的编程方式:C语言代表的过程性语言、C++在C语言基础上添加的类代表的面向对象语言、C+......
  • 【学习笔记】Matlab和python双语言的学习(最大最小化规划)
    文章目录前言一、最大最小化规划二、选址问题三、代码实现----Matlab1.Matlab的`fminimax`函数2.Matlab代码四、代码实现----python总结前言通过模型算法,熟练对Matlab和python的应用。学习视频链接:https://www.bilibili.com/video/BV1EK41187QF?p=28&vd_sour......
  • 想学习人工智能、大语言模型?这份学习路线与免费学习资源最值得推荐
    想学习人工智能吗?但不知道如何开始?要熟练掌握人工智能相关的技术,光学习很多课程是不够的。为了摆脱只是跟着教程学习,你需要亲自动手,从头开始编写算法,动手实践,并通过使用人工智能解决问题来做一些有趣的边项目。这篇文章试图创建一份免费的课程路径,希望对大家学习有帮助。(注......
  • LLM学习笔记-位置编码篇
    在Transformer模型中,位置编码(PositionalEncoding)的引入是为了补充自注意力机制(Self-Attention)在捕捉序列位置信息方面的不足。自注意力机制是Transformer的核心,但它对输入序列的位置信息并不敏感。具体来说,Transformer模型对输入序列中的每个元素进行处理时是并行的,而不是像传统......
  • 机器学习中的两个重要函数--sigmoid和softmax
    机器学习中,常常见到两个函数名称:sigmoid和softmax。前者在神经网络中反复出现,也被称为神经元的激活函数;后者则出现在很多分类算法中,尤其是多分类的场景,用来判断哪种分类结果的概率更大。本文主要介绍这两个函数的定义,形态,在算法中的作用,以及两个函数之间的联系。1.sigmoid函数......
  • c语言11天笔记
    函数的概述函数:实现一定功能的,独立的代码模块。我们的函数一定是先定义,后使用。使用函数的优势:1.我们可以通过函数提供功能给别人使用。当然我们也可以使用别人提供的函数,减少代码量。2.借助函数可以减少重复性的代码。3.实现结构化(模块化)程序设计思想:结构化程序设......
  • 《数据资产管理核心技术与应用》读书笔记-第二章:元数据的采集与存储
    《数据资产管理核心技术与应用》是清华大学出版社出版的一本图书,全书共分10章,第1章主要让读者认识数据资产,了解数据资产相关的基础概念,以及数据资产的发展情况。第2~8章主要介绍大数据时代数据资产管理所涉及的核心技术,内容包括元数据的采集与存储、数据血缘、数据质量、数据监控与......
  • Redux 及Redux-Toolkit 使用笔记及简易实现
    Redux及Redux-Toolkit使用笔记及简易实现依赖的包npminstall@reduxjs/toolkitreact-redux创建Store并且将它注入到app中。一般使用configureStore({reducers:{}}),这种方式,我们可以在各个模块里面定义各自的reducer,然后在store里面使用它。这个方法返回的就是store的实......