数位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]\)表示位 ...
随机推荐
- HDU 4251 The Famous ICPC Team Again 主席树
The Famous ICPC Team Again Problem Description When Mr. B, Mr. G and Mr. M were preparing for the ...
- ios本地推送
#import "AppDelegate.h" @interface AppDelegate () @end @implementation AppDelegate //无论程序在 ...
- Eclipse首字母快捷设置
windows->Preference ,然后:
- 关于Char类型数据做cout输出
当用cout 或者 printf()对char 或者 unsigned char类型数据进行输出的时候,默认输出的都是字符,而不是字符对应的数值.如果要输出数值,必须做int 类型数据的强制转换. 例 ...
- java读取properties配置文件信息
一.Java Properties类 Java中有个比较重要的类Properties(Java.util.Properties),主要用于读取Java的配置文件,各种语言都有自己所支持的配置文件,配置 ...
- [HTTP那些事]网络请求API
在Android上,原生API有两个,HttpUrlConnection和HttpClient,它们对封装Socket进行封装,让HTTP请求变得简单.这应该也算框架吧? 想象下,如果没有HttpUr ...
- Spring的Lifecycle
Lifecycle接口定义了每个对象的重要方法,每个对象都有自己的生命周期需求,如下: public interface Lifecycle { void start(); void stop(); ...
- appium运行报错.<init>(Lorg/openqa/selenium/remote/ErrorCodes;Z)V
最近这几天就在学习appium,搭建环境就耗费了很多时间,不得不承认自己够笨的了,然后我把环境搭建好,写完脚本的时候,就报这个错了,当时是从某个群里直接下载的demo,不得不吐槽说,够坑的,是能跑通, ...
- Servlet 获取 ApplicationContext
一般使用Spring完成了注入,在Service或SpringMVC 中可以通过注解的形式来获取 Spring的已经注入的Spring的bean如下所示: @Resource(name = " ...
- bug提交模板
简述所属版本所属模块严重等级优先级分配给[网络情况][前置条件][详情描述] 1. 2. 3.[预期结果][实际结果][历史版本][备注][是否补充用例] 另外: 1.若和界面有关的bug尽量提供对应 ...