首页 > 其他分享 >数位DP

数位DP

时间:2024-04-04 18:25:36浏览次数:17  
标签:string int DP 数位 dp 数字

数位DP一般解决的问题一般是位数极大, 之和组成这个数的数字有关

一般要维护 \(:\) 填到第几个数字, 是否有限制。

Magic Numbers

令 \(F(x)\) 表示 \(\le x\) 的满足条件元素数量

可以发现, 答案 \(F(r) - F(l - 1)\)

状态 \((i, md, flag1, falg2, sum)\) 表示填了前 \(i\) 个数字, 取模后的结果为 \(md\), 前面有没有填入一个不为 \(0\) 的数字, 有没有贴上界。

枚举当前填什么数字, 转移即可。

时间, 空间复杂度 \(O(|r| \cdot m \cdot 18)\)。

#include<bits/stdc++.h>

using namespace std;

const int N = 2005, mod = 1e9 + 7;

/*

dp[i][m][0/1][0/1]  表示填了前 $i$ 个数字, 取模后的结果, 是否有前导0, 是否贴上届

*/

int dp[N][N][3][3], n, m, d, sum;

string l, r;

int DP(string s){
  n = s.size();
  s = '0' + s;
  for(int i = 1; i <= n; ++i){
    for(int j = 0; j < m; ++j){
      for(int op = 0; op <= 1; ++op){
        dp[i][j][op][0] = dp[i][j][op][1] = 0;
      }
    }
  }
  dp[0][0][1][1] = 1;
  for(int i = 1, sum = 0; i <= n; ++i){
    for(int j = 0; j < m; ++j){
      for(int op = 0; op <= 1; ++op){
        for(int k = 0; k <= 9; ++k){
          if(k != d && i % 2 == 1 || i % 2 == 0 && k == d || (op && !k)){
            dp[i][(j * 10 + k) % m][op & (k == 0)][0] = (dp[i][(j * 10 + k) % m][op & (k == 0)][0] + dp[i - 1][j][op][0]) % mod;
          }
        }
      }
    }
    for(int op = 0; op <= 1; ++op){
      for(int k = 0; k <= s[i] - '0'; ++k){
        if(k != d && i % 2 == 1 || i % 2 == 0 && k == d || (op && !k)){
          dp[i][(sum * 10 + k) % m][op & (k == 0)][(s[i] - '0') == k] = (dp[i][(sum * 10 + k) % m][op & (k == 0)][(s[i] - '0') == k] + dp[i - 1][sum][op][1]) % mod;
        }
      }
    }
    sum = (sum * 10ll + s[i] - '0') % m;
  }
  return (dp[n][0][0][0] + dp[n][0][1][1] + dp[n][0][0][1] + dp[n][0][1][0]) % mod;
}

bool S(string s){
  sum = 0;
  for(int i = 0; i < s.size(); i++){
    sum = (sum * 10ll + s[i] - '0') % m;
    if(s[i] - '0' == d && i % 2 == 0 || s[i] - '0' != d && i % 2 == 1){
      return 0;
    }
  }
  return !sum;
}

int main(){
  cin >> m >> d >> l >> r;
  cout << ((DP(r) - DP(l) + mod) % mod + S(l)) % mod;
  return 0;
}

标签:string,int,DP,数位,dp,数字
From: https://www.cnblogs.com/liuyichen0401/p/18114431

相关文章

  • GDPU 竞赛技能实践 天码行空6
    ......
  • 网络基础二——传输层协议UDP与TCP
    九、传输层协议​传输层协议有UDP协议、TCP协议等;​两个远端机器通过使用"源IP",“源端口号”,“目的IP”,“目的端口号”,"协议号"来标识一次通信;9.1端口号的划分​0-1023:知名端口号,HTTP,HTTPS,FTP,SSH等应用层协议,他们的端口号都是固定的;如:ssh使用的是22号端口,ftp(rzsz使......
  • ffmpeg tcp/udp 拉流
    参考文章:ffmpeg命令分析-拉取TCP流FFmpeg实现rtp推流ffmpeg除了拉取rtsp,hsl等协议外,也支持直接通过tcp/udp推拉流url格式为udp://ip:port或tcp://ip:port注意:udp或tcp有主被动的概念:主动:自己作为客户端,从服务端拉流被动:自己作为服务端,等待客户端推流直接使用tcp/u......
  • 测试UDP端口是否开放
    软件下载地址:https://nmap.org/download.htmlwindows安装后,添加下系统路径 命令说明:>ncat-hNcat7.94(https://nmap.org/ncat)Usage:ncat[options][hostname][port]Optionstakingatimeassumeseconds.Append'ms'formilliseconds,'s'forsec......
  • 蓝桥杯算法集训 - Week 5:树状数组、各类DP算法
    蓝桥杯算法集训-Week5本系列随笔用于整理AcWing题单——《蓝桥杯集训·每日一题2024》的系列题型及其对应的算法模板。一、树状数组树状数组是一种数据结构,可以快速地完成以下两个操作:将第i个数加上c快速求前缀和,即任意区间[i,j]的和Ⅰ、代码模板//树状数组长度......
  • 动态规划---线性dp1
    7-3最大子序列总和给定K个整数序列{N1,N2,...,NK}。连续子序列定义为{Ni,Ni+1,...,Nj},其中1≤i≤j≤K。最大子序列是具有最大元素总和的连续子序列。例如,给定序列{-2,11,-4,13,-5,-2},其最大子序列为{11,-4,13},最大和为20。现在,您应该找到最大的总和,以及......
  • java中获取项目路径包路径域名classpath路径buildPath路径
    /** *获取项目路径 *@returnnull或项目路径 *@throwsIOException */ publicstaticStringgetPojectPath(){ Filedirectory=newFile("");//参数为空 try{ returndirectory.getCanonicalPath(); }catch(IOExceptione){ e.printStackT......
  • 动态规划区间DP
    动态规划区间DP普通区间DP石子合并(蓝桥官网1233)#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=300;intn,a[N],s[N],f[N][N];signedmain(){cin>>n;memset(f,127,sizeof(f));//初始化f为较大值for(inti=1;i<=......
  • P7219 [JOISC2020] 星座 3【笛卡尔树+整体dp】
    P7219[JOISC2020]星座3笛卡尔树+整体dp(线段树合并维护dp)考虑转化题意,不存在矩形为星座,即对于每个极大矩形中都只有一颗星星。而观察题目的方格,对于两个位置是否能够成为一个矩形,只和两个位置的区间最大值(小白船的位置)有关①。图中的红蓝矩形即为两个极大矩形。将删除星......
  • 三道dp的题解报告
    三道dp的题解报告圆题目来源牛客练习赛122D题练习赛链接https://ac.nowcoder.com/acm/contest/75768题面原题面为中文就直接放原题面截图了。解法事实上,把\(n\)与\(1\)断掉,断环为链,把原来的线段看成区间,线段相交就是区间之间部分覆盖(区间有重复部分但是没有相互包含关......