数位DP HDU3555
Bomb
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 15025 Accepted Submission(s): 5427
counter-terrorists found a time bomb in the dust. But this time the
terrorists improve on the time bomb. The number sequence of the time
bomb counts from 1 to N. If the current number sequence includes the
sub-sequence "49", the power of the blast would add one point.
Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?
first line of input consists of an integer T (1 <= T <= 10000),
indicating the number of test cases. For each test case, there will be
an integer N (1 <= N <= 2^63-1) as the description.
The input terminates by end of file marker.
1
50
500
1
15
From 1 to 500, the numbers that include the sub-sequence "49" are "49","149","249","349","449","490","491","492","493","494","495","496","497","498","499",
so the answer is 15.
/*
本题与HDU2089相似,把那道题的代码改了一下找出了不含49的,然后用总数减去,简单粗暴,当然有更好的方法。
*/
#include<iostream>
#include<string>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<queue>
#include<stack>
using namespace std;
int t;
long long dp[][],n;
void init()
{
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
for(int k=;k<;k++)
{
if(j==&&k==) continue;
dp[i][j]+=dp[i-][k];
}
}
}
}
long long insum(long long n)
{
long long sum=;
int lne=,c[]={};
while(n)
{
c[lne++]=n%;
n/=;
}
for(int i=lne-;i>;i--)
{
for(int j=;j<c[i];j++) //j不能等于c[i],因为dp[i][j]中的j代表第i位取j时的总数,而j后面的数
//要全部遍历一遍,这里j后面并非取全部数而是取到给出的数的后几位
{
if(j==&&c[i+]==) continue;
sum+=dp[i][j];
}
if(c[i]==&&c[i+]==) break;
}
return sum;
}
int main()
{
scanf("%d",&t);
while(t--)
{
memset(dp,,sizeof(dp));
dp[][]=;
cin>>n;
n+=;
init();
long long a=insum(n);
cout<<n-a<<endl;
}
return ;
} /*
别人的一个更好的方法。很难想到。
*/
#include<iostream>
#include<string>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<queue>
#include<stack>
using namespace std;
int t;
long long dp[][],n; //dp[i][0]表示到第i位没有49的个数,dp[i][1]表示到第i位没有49但第i位是9的个数,
//dp[i]][2]表示到第i位包含49的个数。
void init()
{
dp[][]=; //初始化
dp[][]=;
dp[][]=;
for(int i=;i<;i++)
{
dp[i][]=*dp[i-][]-dp[i-][]; //到第i位没有49的个数等于第i位依次取0~9连上后面没有49的,
//然后去掉第i位取4,i-1位为9的情况。
dp[i][]=dp[i-][]; //第i位是9时
dp[i][]=*dp[i-][]+dp[i-][]; //到第i位包含49的个数等于第i位依次取0~9连上后面包含49的,
//再加上第i位取4时,i-1位是9的情况。
}
}
long long insum(long long n)
{
long long sum=;
int c[]={};
int cnt=;
while(n)
{
c[cnt++]=n%;
n/=;
}
bool flag=false;
for(int i=cnt-;i>;i--) //从高位到低位依次枚举
{
sum+=dp[i-][]*c[i]; //到第i-1位包含49,就加上0~c[i]个
if(flag) sum+=dp[i-][]*c[i];
else
{
if(c[i]>) sum+=dp[i-][]; //如果第i位大于4了,并且i-1是9,则一定包含49.
}
if(c[i+]==&&c[i]==) flag=true; //当从高位出现49之后后面dp[i][0]就无意义了,全加上
}
return sum;
}
int main()
{
scanf("%d",&t);
{
while(t--)
{
scanf("%lld",&n);
init();
printf("%lld\n",insum(n+)); //计算结果不包含n本身
}
}
return ;
}
//记忆化搜索法
#include<iostream>
#include<string>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<queue>
#include<stack>
using namespace std;
long long n;
int t;
long long dp[][];
int c[];
long long dfs(int lne,int have,int lim)
{
if(lne<=)
return have==;
if(!lim&&dp[lne][have]!=-)
return dp[lne][have];
long long ans=;
int nnum=lim?c[lne]:;
for(int i=;i<=nnum;i++)
{
int nhave=have;
if(have==&&i==) nhave=;
if(have==&&i!=&&i!=) nhave=;
if(have==&&i==) nhave=;
ans+=dfs(lne-,nhave,lim&&i==nnum);
}
if(!lim)
dp[lne][have]=ans;
return ans;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%lld",&n);
memset(dp,-,sizeof(dp));
int cnt=;
while(n)
{
c[++cnt]=n%;
n/=;
}
c[cnt+]=;
printf("%lld\n",dfs(cnt,,));
}
return ;
}
数位DP HDU3555的更多相关文章
- [暑假集训--数位dp]hdu3555 Bomb
The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the ti ...
- 数位dp浅谈(hdu3555)
数位dp简介: 数位dp常用于求区间内某些特殊(常关于数字各个数位上的值)数字(比如要求数字含62,49): 常用解法: 数位dp常用记忆化搜索或递推来实现: 由于记忆化搜索比较好写再加上博主比较蒟, ...
- hdu3555 数位dp
Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Subm ...
- hdu3555 Bomb (记忆化搜索 数位DP)
http://acm.hdu.edu.cn/showproblem.php?pid=3555 Bomb Time Limit: 2000/1000 MS (Java/Others) Memory ...
- hdu---(3555)Bomb(数位dp(入门))
Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submi ...
- hdu3555 Bomb 数位DP入门
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 简单的数位DP入门题目 思路和hdu2089基本一样 直接贴代码了,代码里有详细的注释 代码: ...
- 【Hdu3555】 Bomb(数位DP)
Description 题意就是找0到N有多少个数中含有49. \(1\leq N \leq2^{63}-1\) Solution 数位DP,与hdu3652类似 \(F[i][state]\)表示位 ...
- 【hdu3555】Bomb 数位dp
题目描述 求 1~N 内包含数位串 “49” 的数的个数. 输入 The first line of input consists of an integer T (1 <= T <= 1 ...
- [Hdu3555] Bomb(数位DP)
Description 题意就是找0到N有多少个数中含有49. \(1\leq N \leq2^{63}-1\) Solution 数位DP,与hdu3652类似 \(F[i][state]\)表示位 ...
随机推荐
- Python入门神图
国外某小哥制作的Python入门神图
- AOP静态代理解析1-标签解析
AOP静态代理使用示例见Spring的LoadTimeWeaver(代码织入) Instrumentation使用示例见java.lang.instrument使用 AOP的静态代理主要是在虚拟机启动 ...
- json返回数据库的时间格式为/Date(1477294037000)/,怎样在前台进行格式化转换
方法一: 原理是取中间的数,再转换成js的Date类型 function ChangeDateFormat(val) { if (val != null) { var date = new Date( ...
- ArcGIS 点到直线的距离
/****点到直线的距离*** * 过点(x1,y1)和点(x2,y2)的直线方程为:KX -Y + (x2y1 - x1y2)/(x2-x1) = 0 * 设直线斜率为K = (y2-y1)/(x2 ...
- Python基础11- 函数之自定义函数
自定义函数语法结构:def fun1([x],[y],....): 语句1 语句2 使用def语句来定义函数,在def后依次写出函数名.小括号.参数(可无).冒号,然后缩进写函数体 1.无参函数:de ...
- git 学习笔记5--rm & mv,undo
rm 删除文件 rm <file> #Unix删除文件 git rm <file> # git删除文件 git rm -f <file> # git强制删除文件 g ...
- sparklyr包--实现R与Spark接口
1.sparklyr包简介 Rstudio公司发布的sparklyr包具有以下几个功能: 实现R与Spark的连接: sparklyr包提供了一个完整的dplyr后端,可筛选并聚合Spark数据集,接 ...
- iOS学习02C语言分支结构
1. BOOL类型 返回值:真:YES 假:NO BOOL数据类型占一个字节的内存空间,占位符为%d. 计算机在识别时,YES就替换成1,NO就替换成0. bool是C语言中的布尔类型,返回值为tr ...
- Mongoose学习参考文档——基础篇
Mongoose学习参考文档 前言:本学习参考文档仅供参考,如有问题,师请雅正 一.快速通道 1.1 名词解释 Schema : 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力 Model ...
- Android数据存储的三种方式:SharePreferences , file , SQLite
(1)SharePreferences: 存入: SharedPreferences setter = this.getSharedPreferences("spfile", 0) ...