【ARC075F】Mirrored 搜索/数位dp
Description
给定正整数DD,求有多少个正整数NN,满足rev(N)=N+Drev(N)=N+D,其中rev(N)rev(N)表示将NN的十进制表示翻转来读得到的数
Input
一个正整数DD
Output
满足上述条件的正整数的个数
Sample Input
Case 1:
63
Case 2:
75
Case 3:
864197532
Sample Output
Case 1:
2
Case 2:
0
Case 3:
1920
HINT
1≤D≤1091≤D≤109
样例1解释:81=18+63,92=29+63
Sol
我们把题目转化成rev(n)-n=d,然后折半搜索,只搜一半,另一半可以直接计算,这样的复杂度为\(O(2^{18})\)左右。
然而还是有更强的做法的,这个不用搜。。可以dp。。而且复杂度只有\(O(d^2*10)\),具体地,在这里:orzDTZ,写得非常详细。
Code
搜索:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int D,cnt[19],ans;ll b[20];
void dfs(int x,ll res,int L,int now)
{
if(x>(L>>1)-1){if(res==D) ans+=now*(L&1?10:1);return;}
ll i=-9ll;while(i<9ll&&res+(i+1ll)*(b[L-x-1]-b[x])<=D) ++i;
dfs(x+1,res+i*(b[L-x-1]-b[x]),L,now*(x==0&&i>=0?cnt[i+9]-1:cnt[i+9]));
if(++i<=9) dfs(x+1,res+i*(b[L-x-1]-b[x]),L,now*(x==0&&i>=0?cnt[i+9]-1:cnt[i+9]));
}
int main()
{
scanf("%d",&D);
b[0]=1ll;for(int i=1;i<19;++i) b[i]=b[i-1]*10ll;
for(int i=0;i<=9;++i) for(int j=0;j<=9;++j) ++cnt[i-j+9];
for(int i=1;i<=18;++i) dfs(0,0,i,1);
printf("%d",ans);
}
dp:
#include <bits/stdc++.h>
using namespace std;
int d[10005],f[10005][2][2],L,ans,lim,P=1e9+7;char D[10005];
int dp(int n)
{
int m=n>>1,res=0;
for(int i=0;i<=m;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) f[i][j][k]=0;
f[0][0][0]=1;
for(int i=0;i<m;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) if(f[i][j][k]) for(int x=0,y,j1,k1;x<10;x++)
{
k1=x+d[i+1]+k,y=k1%10,k1/=10,j1=10*j+x-y-d[n-i];
if(j1<0||j1>1||(!i&&(!x||!y))) continue;
(f[i+1][j1][k1]+=f[i][j][k])%=P;
}
if(n&1) for(int j=0,mid=(n+1)>>1;j<2;j++) for(int k=0;k<2;k++) if(f[m][j][k]) for(int x=0,y;x<10;x++)
{
y=x+d[mid]+k;
if((x==y%10)&&(y/10==j)) (res+=f[m][j][k])%=P;
}
if(!(n&1)) for(int j=0;j<2;j++) (res+=f[m][j][j])%=P;
return res;
}
int main()
{
scanf("%s",D+1);L=strlen(D+1);lim=L<<1;
for(int i=1;i<=L;i++) d[L-i+1]=D[i]-'0';
for(int i=max(2,L);i<=lim;i++) (ans+=dp(i))%=P;
printf("%d\n",(ans+P)%P);
}
【ARC075F】Mirrored 搜索/数位dp的更多相关文章
- hdu3555 Bomb (记忆化搜索 数位DP)
http://acm.hdu.edu.cn/showproblem.php?pid=3555 Bomb Time Limit: 2000/1000 MS (Java/Others) Memory ...
- UVALive 4864 Bit Counting --记忆化搜索 / 数位DP?
题目链接: 题目链接 题意:如果一个数二进制n有k位1,那么f1[n] = k,如果k有s位二进制1,那么f2[n] = f1[k] = s. 如此往复,直到fx[n] = 1,此时的x就是n的”K ...
- hdu_3562_B-number(记忆化搜索|数位DP)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3652 题意:给你一个n,为比n小的能整除13并数字中有13的数有多少个 题解:记忆化搜索:记dp[i] ...
- 【记忆化搜索/数位DP】zznu2175(长度为n的含有ACM的字符串)
随机字符串 题目描述 起名字什么的最麻烦,我们来生成一些随机字符串吧 生成的字符串当然是有要求的: .长度不能超过n .字符串中仅包含大写字母 .生成的字符串必须包含字符串“ACM” ok,是不是很简 ...
- 数位DP HDU3652
B-number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- Hdu 3652 B-number (同余数位DP)
题目链接: Hdu 3652 B-number 题目描述: 给出一个数n,问 [1, n]区间内有几个数能被13整除并且还有13这个子串? 解题思路: 能整除的数位DP,确定好状态随便搞搞就能过了.d ...
- 数位dp/记忆化搜索
一.引例 #1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an ...
- [hihocoder 1033]交错和 数位dp/记忆化搜索
#1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1 ...
- luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索
题目链接 luogu P2657 [SCOI2009]windy数 题解 我有了一种所有数位dp都能用记忆话搜索水的错觉 代码 #include<cstdio> #include<a ...
随机推荐
- spark集群配置以及java操作spark小demo
spark 安装 配置 使用java来操作spark spark 安装 tar -zxvf spark-2.4.0-bin-hadoop2.7.tgz rm spark-2.4.0-bin-hadoo ...
- 手机自带输入法emoji表情的输入,提交及显示——前端解决方案
体验更优排版请移步原文:http://blog.kwin.wang/programming/emoji-transform-commit.html 之前就遇到过需要前端支持用户输入并提交emoji表情 ...
- Mysql问题随记
[用户创建并授权远程访问] CREATE USER 'username'@'host' IDENTIFIED BY 'password’; @后面跟主机地址,即这个用户可以从哪些地址访问数据库,l ...
- Linux字符设备驱动实现
Linux字符设备驱动实现 要求 编写一个字符设备驱动,并利用对字符设备的同步操作,设计实现一个聊天程序.可以有一个读,一个写进程共享该字符设备,进行聊天:也可以由多个读和多个写进程共享该字符设备,进 ...
- Bypassing iPhone Code Signatures
[Bypassing iPhone Code Signatures] Starting with the recent beta releases of the iPhoneOS, Apple has ...
- codeforce 460DIV2 D题
感觉这个题不错,对拓扑排序有了更深的了解,用两种拓扑排序都写了些试试. dfs #include <cstdio> #include <algorithm> #include ...
- ubuntu 安装两个版本的Anaconda
1.下载anaconda2/anaconda3,下载地址:https://www.anaconda.com/download/#linux,anaconda官网如下所示,选择对应版本下载. 2.使用如 ...
- 运用alarm系统调用检测网络是否断开
比如对于一个Server/Client程序,Client会每隔一定时间(比如TIME_OUT_CLIENT)会向Server发送“CheckConnect”信息,Server收到这个信息会调用回调函数 ...
- UOJ 176 新年的繁荣
挺妙的解法. 发现边权很小,我们可以考虑从大到小枚举边权来进行$kruskal$算法,这样子对于每一个边权$i$,我们只要枚举$0 \leq j < m$,找到一个点使它的点权为$i | 2^j ...
- selenium+phantomjs解析JS
背景知识: PhantomJS 是一个基于WebKit的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS 选择器, J ...