题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4507

题目大意:

找到区间 \([L,R]\) 范围内所有满足如下条件的数的 平方和

  • 不包含‘7’;
  • 不能被 7 整除;
  • 各位之和不能被 7 整除。

注意:求的是满足条件的数的 平方和

解题思路:

使用 数位DP 尽情求解。

但是因为这里求的是满足要求的元素的平方和,而不是元素的个数。

所以我们不能简单地开long long来存放结果,

而是开一个结构体来存放结果,结构体中需要包含三个元素:

  • 满足要求的元素个数(用 cnt 表示);
  • 满足要求的元素的和(用 sum 表示);
  • 满足要求的元素的平方和(用 sum2 表示)

定义状态 \(f[pos][pre][ts]\) 表示:

  • 当前在第 \(pos\) 位;
  • 前一位(即第 \(pos+1\) 位)放置的数 mod 7为 \(pre\)
  • 前面所有位上的数的和 mod 7 的结果为 \(ts\)

时对应的信息(包括元素个数、和、平方和)。

那么如何获得状态转移方程呢?

每次查找的数字的前几位都是一样的,比如对于三位数:

\[abc
\]

假设第一位枚举了2;即

\[2|b|c
\]

那么之后枚举到的数字就是 \(200+x\) 。

如果 \(200\) - \(300\) 之间只有 \(231\) ,\(230\) 和 \(233\) 满足条件,那么 \(200\) - \(300\) 之间的数的平方和就为

\[230^2+231^2+233^2
\]

也就等于

\[(200+30)^2+(200+31)^2+(200+33)^2
\]

展开后得到:

\[3 \times 200^2+2 \times 200 \times (30+31+33)+(30^2+31^2+3^32)
\]

并且我们可以据此得到状态转移了。

(上述思路来自 Ender的博客 ,不过他的公式推到错了,多乘了一个3,所以还是看我的计算公式即可)

实现的代码如下:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const long long MOD = 1000000007LL;
  4. struct Node {
  5. long long cnt; // 数量
  6. long long sum; // 和
  7. long long sum2; // 平方和
  8. Node () {};
  9. Node (long long _cnt, long long _sum, long long _sum2) {
  10. cnt = _cnt; sum = _sum; sum2 = _sum2;
  11. }
  12. } f[22][7][7];
  13. int a[22];
  14. bool vis[22][7][7];
  15. long long pow10[22];
  16. void init() {
  17. memset(vis, 0, sizeof(vis));
  18. pow10[0] = 1;
  19. for (int i = 1; i < 22; i ++) pow10[i] = pow10[i-1] * 10 % MOD;
  20. }
  21. Node dfs(int pos, int pre, int ts, bool limit) {
  22. if (pos < 0) {
  23. int cnt = 1;
  24. if (pre == 0) cnt = 0; // 不能被7整除
  25. if (ts == 0) cnt = 0; // 所有数位的和不能被7整除
  26. return Node(cnt, 0, 0);
  27. }
  28. if (!limit && vis[pos][pre][ts]) return f[pos][pre][ts];
  29. int up = limit ? a[pos] : 9;
  30. Node res = Node(0, 0, 0);
  31. for (int i = 0; i <= up; i ++) {
  32. if (i == 7) continue; // 不能包含7
  33. Node tmp = dfs(pos-1, (pre*10+i)%7, (ts+i)%7, limit && i==up);
  34. long long tmp_cnt = tmp.cnt;
  35. long long tmp_sum = tmp.sum;
  36. long long tmp_sum2 = tmp.sum2;
  37. long long t = pow10[pos] * i % MOD;
  38. long long now_sum = (t * tmp_cnt + tmp_sum) % MOD;
  39. long long now_sum2 = (tmp_cnt * t % MOD * t % MOD + 2LL * t % MOD * tmp_sum % MOD + tmp_sum2) % MOD;
  40. res.cnt = (res.cnt + tmp_cnt) % MOD;
  41. res.sum = (res.sum + now_sum) % MOD;
  42. res.sum2 = (res.sum2 + now_sum2) % MOD;
  43. }
  44. if (!limit && !vis[pos][pre][ts]) {
  45. vis[pos][pre][ts] = true;
  46. f[pos][pre][ts] = res;
  47. }
  48. return res;
  49. }
  50. long long get_num(long long x) {
  51. int pos = 0;
  52. while (x) {
  53. a[pos++] = x % 10;
  54. x /= 10;
  55. }
  56. return dfs(pos-1, 0, 0, true).sum2;
  57. }
  58. int T;
  59. long long L, R;
  60. int main() {
  61. init();
  62. scanf("%d", &T);
  63. while (T --) {
  64. scanf("%lld%lld", &L, &R);
  65. printf("%lld\n", (get_num(R) - get_num(L-1) + MOD) % MOD);
  66. }
  67. return 0;
  68. }

HDU4507 吉哥系列故事——恨7不成妻 题解 数位DP的更多相关文章

  1. 2018.09.27 hdu4507吉哥系列故事——恨7不成妻(数位dp)

    传送门 一道比较综合的数位dp. 维护三个值:[L,R][L,R][L,R] 区间中与7无关的数的数量,与7无关的数之和,与7无关的数的的平方和. 然后可以用第一个值推第二个,第一个和第二个值推第三个 ...

  2. 吉哥系列故事——恨7不成妻(数位dp)

    吉哥系列故事--恨7不成妻 传送门 Problem Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥 ...

  3. HDU - 4507 - 吉哥系列故事——恨7不成妻(数位DP,数学)

    链接: https://vjudge.net/problem/HDU-4507 题意: 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都 ...

  4. hdu_4507_吉哥系列故事——恨7不成妻(鬼畜数位DP)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4507 题意:中文,不解释,注意的是求的是合法数字的平方和,即(a+b+c+……)^2 题解:数位DP, ...

  5. HDU 4507 吉哥系列故事――恨7不成妻(数位DP+结构体)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4507 题目大意:如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关 1.整数中某一位是7: ...

  6. HDU 4507 吉哥系列故事——恨7不成妻 (数位DP)

    题意: 如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关: 1.整数中某一位是7: 2.整数的每一位加起来的和是7的整数倍: 3.这个整数是7的整数倍: 给定一个区间[L,R],问在此区 ...

  7. [HDU4507]吉哥系列故事——恨7不成妻

    [HDU4507]吉哥系列故事--恨7不成妻 试题描述 单身!依然单身!吉哥依然单身!DS级码农吉哥依然单身!所以,他生平最恨情人节,不管是214还是77,他都讨厌!吉哥观察了214和77这两个数,发 ...

  8. hdu4507吉哥系列故事——恨7不成妻 (数位dp)

    Problem Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: ...

  9. HDU-4507 吉哥系列故事——恨7不成妻 数位DP

    题意:给定区间[L, R]求区间内与7无关数的平方和.一个数当满足三个规则之一则认为与7有关:1.整数中某一位是7:2.整数的每一位加起来的和是7的整数倍:3.这个整数是7的整数倍: 分析:初看起来确 ...

随机推荐

  1. oracle函数 mod(x,y)

    [功能]返回x除以y的余数 [参数]x,y,数字型表达式 [返回]数字 [示例] select mod(23,8),mod(24,8) from dual; 返回:7,0

  2. php 位运算 3<<2;

  3. H3C 常用设备管理命令

  4. H3C TCP连接的拆除

  5. MySQL数据库字符集和整理

    MySQL数据库字符集和整理(2009-11-20 22:23:37) mysql数据库 it    其实这个表在MySQL数据库中通过phpMyAdmin就能看到,icech只是把表格整理了一下方便 ...

  6. supersockets服务器配置热更新

    Keywords: 配置,热更新 此功能能够允许你在不重启服务器的前提下更新服务器实例的配置. (仅限1.6.5及其以上版本)

  7. ThinkPHP商城实战

    ThinkPHP3.2.3商城实战教程,需要的联系我,QQ:1844912514 千万级php电商秒杀项目实战  ,需要的联系我,QQ:1844912514

  8. poj 1787 Charlie's Change (多重背包可作完全背包)

    Charlie's Change Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 3792   Accepted: 1144 ...

  9. vue-router在新窗口打开页面

    1. <router-link>标签实现新窗口打开: <router-link target="_blank" :to="{path:'/app/dat ...

  10. Flex AIR应用拍照功能(Android和IOS版本)

    说明: 使用AIR处理拍照后的回调.照片文件的保存功能时,针对于IOS和Android两个平台是有所不同的. 但.关于如何调用摄像头进行拍照这个功能,Android和IOS是一致的. 技术实现: 1) ...