codeforces 628D Magic Numbers (数位dp)
2016-03-05 11:49
513 查看
题目: 这里
题意:给定数字m, d 和2个长度小于2000 的数字a, b,问区间[a, b]内有多少个数偶数位只包含数字d,奇数位都不含有数字d,且能被m整除。
思路:
数位dp,dp[i][j] 表示前 i 个数字模为 j 的方法数,分类讨论 i 是偶数位还是奇数位就可以了。
代码:
View Code
题意:给定数字m, d 和2个长度小于2000 的数字a, b,问区间[a, b]内有多少个数偶数位只包含数字d,奇数位都不含有数字d,且能被m整除。
思路:
数位dp,dp[i][j] 表示前 i 个数字模为 j 的方法数,分类讨论 i 是偶数位还是奇数位就可以了。
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll MOD = 1e9+7; const int N = 2020; char a , b ; int m, n; int dg ; ll f ; inline ll add(ll x, ll y) { x = x + y; return x >= MOD ? x-MOD : x; } ll dfs(int i, int s, bool flag, bool e) { // dp[i][s] , flag 表示奇数还是偶数,e代表边界 if(i == -1) return s == 0; if(!e && ~f[i][s]) return f[i][s]; ll res = 0LL; int u = e ? dg[i] : 9; for(int d = 0; d <= u; ++d) { if(flag == 1 && d == n) continue; if(flag == 0 && d != n) continue; res = add(res, dfs(i-1, (s*10+d)%m, flag^1, e && d==u)); } return e ? res : f[i][s] = res; } void deal(int& len) { for(int i = 0; i < len; ++i) { if(dg[i] == 0) dg[i] = 9; else { --dg[i]; break; } } return ; } ll solve(char c[], bool fg) { int len = strlen(c); for(int i = 0; i < len; ++i) dg[i] = c[len-1-i] - '0'; if(fg) deal(len); return dfs(len-1, 0, 1, 1); } int main() { scanf("%d %d", &m, &n); scanf("%s %s", a, b); memset(f, -1, sizeof f); printf("%I64d\n", add(solve(b, 0) - solve(a, 1), MOD)); return 0; }
View Code
相关文章推荐
- Windows系统下Yaf框架的安装
- ConcurrentHashMap -- 线程安全的hashmap
- 递归思想,实现字符串反转
- 字典序最小问题
- eclipse安装java web开发环境
- 图像叠加及透明度的调整在matlab下实现
- IIS 多站点HTTPS加密及自动http跳转到https
- [Programming WCF Services]Chapter 1. WCF Essentials - EndPoint
- 我与小娜(26):冷酷机器与情感人类对弈,你站在哪一边?
- rebmuNnmuloCteehSlecxE.171
- 手把手教你编写一个具有基本功能的shell(已开源)
- sed字符串替换
- ubuntu 打开系统监视器
- 2016.03.05
- mysql读写分离之amoeba
- input子系统分析
- 106. Construct Binary Tree from Inorder and Postorder Traversal
- c语言概述
- 第三方库文件ViewPagerIndicator实现由Eclipse到Android Studio的完美迁移——项目迁移一
- Eclipse使用入门教程