HDU4507 吉哥系列故事——恨7不成妻 题解 数位DP
题目链接: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\)
时对应的信息(包括元素个数、和、平方和)。
那么如何获得状态转移方程呢?
每次查找的数字的前几位都是一样的,比如对于三位数:
\]
假设第一位枚举了2;即
\]
那么之后枚举到的数字就是 \(200+x\) 。
如果 \(200\) - \(300\) 之间只有 \(231\) ,\(230\) 和 \(233\) 满足条件,那么 \(200\) - \(300\) 之间的数的平方和就为
\]
也就等于
\]
展开后得到:
\]
并且我们可以据此得到状态转移了。
(上述思路来自 Ender的博客 ,不过他的公式推到错了,多乘了一个3,所以还是看我的计算公式即可)
实现的代码如下:
#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007LL;
struct Node {
long long cnt; // 数量
long long sum; // 和
long long sum2; // 平方和
Node () {};
Node (long long _cnt, long long _sum, long long _sum2) {
cnt = _cnt; sum = _sum; sum2 = _sum2;
}
} f[22][7][7];
int a[22];
bool vis[22][7][7];
long long pow10[22];
void init() {
memset(vis, 0, sizeof(vis));
pow10[0] = 1;
for (int i = 1; i < 22; i ++) pow10[i] = pow10[i-1] * 10 % MOD;
}
Node dfs(int pos, int pre, int ts, bool limit) {
if (pos < 0) {
int cnt = 1;
if (pre == 0) cnt = 0; // 不能被7整除
if (ts == 0) cnt = 0; // 所有数位的和不能被7整除
return Node(cnt, 0, 0);
}
if (!limit && vis[pos][pre][ts]) return f[pos][pre][ts];
int up = limit ? a[pos] : 9;
Node res = Node(0, 0, 0);
for (int i = 0; i <= up; i ++) {
if (i == 7) continue; // 不能包含7
Node tmp = dfs(pos-1, (pre*10+i)%7, (ts+i)%7, limit && i==up);
long long tmp_cnt = tmp.cnt;
long long tmp_sum = tmp.sum;
long long tmp_sum2 = tmp.sum2;
long long t = pow10[pos] * i % MOD;
long long now_sum = (t * tmp_cnt + tmp_sum) % MOD;
long long now_sum2 = (tmp_cnt * t % MOD * t % MOD + 2LL * t % MOD * tmp_sum % MOD + tmp_sum2) % MOD;
res.cnt = (res.cnt + tmp_cnt) % MOD;
res.sum = (res.sum + now_sum) % MOD;
res.sum2 = (res.sum2 + now_sum2) % MOD;
}
if (!limit && !vis[pos][pre][ts]) {
vis[pos][pre][ts] = true;
f[pos][pre][ts] = res;
}
return res;
}
long long get_num(long long x) {
int pos = 0;
while (x) {
a[pos++] = x % 10;
x /= 10;
}
return dfs(pos-1, 0, 0, true).sum2;
}
int T;
long long L, R;
int main() {
init();
scanf("%d", &T);
while (T --) {
scanf("%lld%lld", &L, &R);
printf("%lld\n", (get_num(R) - get_num(L-1) + MOD) % MOD);
}
return 0;
}
HDU4507 吉哥系列故事——恨7不成妻 题解 数位DP的更多相关文章
- 2018.09.27 hdu4507吉哥系列故事——恨7不成妻(数位dp)
传送门 一道比较综合的数位dp. 维护三个值:[L,R][L,R][L,R] 区间中与7无关的数的数量,与7无关的数之和,与7无关的数的的平方和. 然后可以用第一个值推第二个,第一个和第二个值推第三个 ...
- 吉哥系列故事——恨7不成妻(数位dp)
吉哥系列故事--恨7不成妻 传送门 Problem Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥 ...
- HDU - 4507 - 吉哥系列故事——恨7不成妻(数位DP,数学)
链接: https://vjudge.net/problem/HDU-4507 题意: 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都 ...
- hdu_4507_吉哥系列故事——恨7不成妻(鬼畜数位DP)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4507 题意:中文,不解释,注意的是求的是合法数字的平方和,即(a+b+c+……)^2 题解:数位DP, ...
- HDU 4507 吉哥系列故事――恨7不成妻(数位DP+结构体)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4507 题目大意:如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关 1.整数中某一位是7: ...
- HDU 4507 吉哥系列故事——恨7不成妻 (数位DP)
题意: 如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关: 1.整数中某一位是7: 2.整数的每一位加起来的和是7的整数倍: 3.这个整数是7的整数倍: 给定一个区间[L,R],问在此区 ...
- [HDU4507]吉哥系列故事——恨7不成妻
[HDU4507]吉哥系列故事--恨7不成妻 试题描述 单身!依然单身!吉哥依然单身!DS级码农吉哥依然单身!所以,他生平最恨情人节,不管是214还是77,他都讨厌!吉哥观察了214和77这两个数,发 ...
- hdu4507吉哥系列故事——恨7不成妻 (数位dp)
Problem Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: ...
- HDU-4507 吉哥系列故事——恨7不成妻 数位DP
题意:给定区间[L, R]求区间内与7无关数的平方和.一个数当满足三个规则之一则认为与7有关:1.整数中某一位是7:2.整数的每一位加起来的和是7的整数倍:3.这个整数是7的整数倍: 分析:初看起来确 ...
随机推荐
- AtCoder Beginner Contest 078 D ABS
光做C了,做完C,就要结束了,看了看D,没看懂那操作啥意思,就扔了. 刚才看了看,突然懂了.. 就是每个人从那堆牌上边拿牌,最少拿一张,最多可以全拿走,然后手里留下最后一张拿到的,其余的都扔掉. 比如 ...
- hdu 3938 Portal (prim+离线)
Problem - 3938 题意是要求出给定权值下,满足要求的点对的数目.所谓的要求是,给出两点,之间会有很多路径,这个点对的最小距离是众多路径中,最短的一条路径的长度,路径长度是路径上最长边的长度 ...
- IDEA 通过数据库生成entity实体类
IDEA利用数据库生成entity类教程 1.在左上角有一个View 选项 2. 然后选择 TOOL Windows 3. 然后选择Database然后会弹出一个窗口 4.选择+号 5.选择data ...
- DirectEvents用法
DirectEvents异步执行服务器端事件 我们首先来看一下Ext.Net DirectEvents的一个最简单用法,通过点击按钮触发服务器端的事件处理方法,并在前台弹出一个提示框. <ext ...
- oracle 用表连接替换EXISTS
通常来说 , 采用表连接的方式比EXISTS更有效率 SELECT ENAME FROM EMP E WHERE EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT_NO ...
- SuperSocket主动从服务器端推送数据到客户端
关键字: 主动推送, 推送数据, 客户端推送, 获取Session, 发送数据, 回话快照 通过Session对象发送数据到客户端 前面已经说过,AppSession 代表了一个逻辑的 socke ...
- hdu 1016 Prime Ring Problem(dfs)
Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- css的一些小问题
这是今天整理的笔记一.属性书写顺序: Formatting Model(布局方式.位置) > Box Model(尺寸) > Typographic(文本相关) > Visual(视 ...
- Python--day43--mysql唯一索引和外键变种之多对多
唯一索引:(unique关键字)unique 名字 (num) 外键的变种:
- SpringSecurity认证流程详解
SpringSecurity基本原理 在之前的文章<SpringBoot + Spring Security 基本使用及个性化登录配置>中对SpringSecurity进行了简单的使用介绍 ...