首页 > 其他分享 >20230401数位DP

20230401数位DP

时间:2023-04-08 23:45:42浏览次数:51  
标签:int 20230401 枚举 num limit dp id DP 数位

数位DP

数位DP通常指在\([l,r]\)区间中有多少个满足条件\(k\)的个树
常见的数据范围都很大

也就是说,
把数字的枚举,变成数字的构造
不要把数字看作是\(10^{18}\)
而把数字看作是\(18\)位数的填数过程
就是把原本枚举的问题转化为了构造的问题

然而数位dp常通过记忆化搜索实现

tips:

1.求区间\([l,r]\)的问题也要常转化为\([1,r]-[1,l-1]\)
2.在枚举前我们需要考虑好枚举的方向,也就是从低到高或从高到低

例题

P8801 [蓝桥杯 2022 国 B] 最大数字

题目
这是一个很典型的数位dp
对于每一位数字
我们从高位到低位枚举其可能变成的数字
而在高位的数字越大越好
所以对于每一位数,我们从\(9\)开始枚举
在这一位第一次递推成功后就break
因为再往下枚举就没有更优解了

//当前枚举到第id位,a,b,当前的答案位number 
void dfs(int id,int a,int b,ll number){
  //1.出口
  if(id==0){
  	ans=max(ans,number);
  	return ;
  }
  //2.能做的事情 
  for(int i=9;i>=0;i--){
  	int acost=(i-num[id]+10)%10;
  	int bcost=(num[id]-i+10)%10;
  	bool flag=false;
    if(a>=acost){
      flag=true;
      dfs(id-1,a-acost,b,number*10+i);
	}
	if(b>=bcost){
	  flag=true;
	  dfs(id-1,a,b-bcost,number*10+i);
	}
	if(flag) break;
  }
}
P8764 [蓝桥杯 2021 国 BC] 二进制问题

题目
同样对于每一位要枚举
但要加上对上界的考虑
枚举不能超过\(n\)
(注意记忆化搜索数组的大小,不要开小了)

//当前枚举到第id位,前面有num个1,这一位是否有限制
ll dfs(int id,int num,int limit){
  //1.出口
  if(id==0||num==k) return num==k;
  if(dp[id][num][limit]>=0) return dp[id][num][limit];
  //2.能做的事情
  ll res=0;
  int bound= limit==1?a[id]:1;
  for(int i=0;i<=bound;i++)
  	res+=dfs(id-1,num+i,limit&&i==bound);
  return dp[id][num][limit]=res;
} 
P4999 烦人的数学作业

题目
和前面一道题没有什么大的区别
但要注意减法取模时要\((a-b+mod) \mod mod\)
而由于多组数据,记忆化数组\(dp\)其实是可以重复使用的
对于每位数,如果后面没有限制,那么\(dp[id][sum]\)是不变的
所以不必每次清空\(dp\)

//当前枚举到第id位,前面数字和为sum,是否达到上界limit
ll dfs(int id,ll sum,int limit){
  //1.出口
  if(id==0) return sum;
  if(!limit&&dp[id][sum]>=0) return dp[id][sum];
  //2.能做的事情 
  ll res=0;
  int bound= limit==1 ? a[id] : 9;
  for(int i=0;i<=bound;i++){
  	res=(res+dfs(id-1,sum+i,limit&&i==bound))%mod;
  }
  if(!limit) dp[id][sum]=res%mod;
  return res%mod;
} 
其他题目

P2657 [SCOI2009] windy 数
P2602 [ZJOI2010] 数字计数
P4798 [CEOI2015 Day1] 卡尔文球锦标赛
P3281 [SCOI2013]数数
P2518 [HAOI2010]计数
P3286 [SCOI2014]方伯伯的商场之旅

标签:int,20230401,枚举,num,limit,dp,id,DP,数位
From: https://www.cnblogs.com/hewanying0622/p/17299586.html

相关文章

  • Java笔记(14) UDP通讯程序Demo
    实现一个简单的UDP通信程序,仅作为笔记使用网络编程中有三要素:IP、端口号和通信协议,分别用来确定对方在互联网上的地址、指定接受数据的软件和确定数据在网络中传输的规则。IP地址IP地址分为IPv4地址和IPv6地址,这里不做讨论。IPv4地址中分为公网地址(万维网使用)和私有地址(局......
  • 数位 dp
    数位\(\text{dp}\)前言谨慎学习此算法。算法讲解AcWing1081.度的数量题意分析:你看到这道题,是不是无从下手?其实题目就是让我们求在\(x\simy\)中,有多少个数分解成\(B\)进制后仅有\(k\)位为\(1\),其余均为\(0\);考虑暴力:从\(x\)枚举到\(y\),将\(i(x\lei\le......
  • 关于 IDP 的五大认知误解
    内部开发者平台(IDP)是近年来在希望加快软件交付和改善开发者体验的企业中得到普及的一个概念。然而,大众对于什么是IDP以及它能为开发者和企业带来什么也有很多困惑和误解。在这篇文章中,我们将尝试解开一些关于平台工程以及IDP的常见误解,以及关于企业该如何避免进入这些误区给出......
  • LightOJ - 1044 Palindrome Partitioning(DP)
    题目大意:给你一个字符串,要求你对字符串进行划分,使得划分出来的子串都是回文串,且子串数量达到最小解题思路:用dp[i]表示前i个字符划分成回文串,需要划分成多少个部分接着枚举j,如果[i,j]回文,那么dp[i]=min(dp[i],dp[j-1]+1)#include<cstdio>#include<cstring>#include<al......
  • UVA - 10003 Cutting Sticks 区间DP
    题目大意:给出一根木棒长l,上面有k个点,要求从这些点切割,每次切割的代价是当前要切割的木棒的长度,求最小的代价解题思路:区间DP:区间动态规划问题一般都是考虑,对于每段区间,他们的最优值都是由几段更小区间的最优值得到,是分治思想的一种应用,将一个区间问题不断划分为更小的区间直至一个......
  • ZOJ - 3469 Food Delivery(区间DP)
    题目大意:有一个餐厅,在X这个位置,送餐速度为v的-1次方,有N个顾客,分别在pos位置,每个顾客都有一个displeasure值,当餐送到该顾客手上时,该顾客的displeasure总值为displeasure值*到手时间问所有顾客的最小displeasure总值和是多少解题思路:首先按位置排个序设dp[i][j][0]为[i,j]这个区......
  • POJ - 1651 Multiplication Puzzle(区间dp)
    题目大意:给你N个数,每次可以选择一个数进行剔除(第一个和最后一个不能选择),选出该数后,sum+=该数左边的数*该数*该数右边的数问最小的sum是多少解题思路:用dp[i][j]表示[i,j]区间被剔除得只剩下i,j的最小sumdp[i][j]=dp[i][k]+dp[k][j]+num[i]*num[k]*num[j]#include......
  • CodeForces - 149D Coloring Brackets(区间DP)
    题目大意:给你一个符合括号规则的字符串,现在要求你将这些括号染色,染色规则如下1.一个括号要么被染成红色,要么被染成蓝色,要么不染2.相邻的括号的颜色不能相同(可以同为无色)3.成对的括号只能有一个被染色问染色的方案数解题思路:0表示不染,1表示红色,2表示蓝色那么成对的括号......
  • POJ - 2955 Brackets(区间dp)
    题目大意:给出一个括号字符串,问这个字符串中符合规则的最长子串的长度解题思路:区间dp,用dp[i][j]表示[i,j]这个区间内有符合规则的最长子串的长度如果str[i]和str[j]能构成()或者[],那么dp[i][j]=dp[i+1][j-1]+2剩下的情况就是dp[i][j]=max(dp[i][j],dp[i][k]+dp[k......
  • POJ - 3666 Making the Grade(DP)
    题目大意:给你一个数组A,要求将这个数组变成数组B,使得Sum(abs(A[i]-B[i]))达到最小,且B是单调的解题思路:因为答案要求输出单调非递增或者单调非递减的的任意一个,那就只考虑单调非递增吧,因为两个的思路是相同的如果要变化的话,且变化的值要达到最小的话,那么只能变成和前一个相同或者......