数位DP HDU3555+CF55D+HDU2089
来源:互联网 发布:淘宝商品佣金查询 编辑:程序博客网 时间:2024/05/22 21:48
数位DP:较为精细的讲解在上面的文章已经提到了,这里就直接说题了
1hdu:2089
http://acm.hdu.edu.cn/showproblem.php?pid=2089
题意:询问[L,R]之间有多少个数没有出现过4,且不存在62相连的情况!
思路:基本的数位dp,记忆化搜索,其中dp[i]都表示的是从1到当前数的答案数,考虑每一位判断是否是4,同时记录下来前一位是否是6,如果是6则当前位不枚举2即可。
#include <iostream>#include<algorithm>#include<stdio.h>#include<string.h>using namespace std;typedef long long ll;ll dp[11][2];ll dig[15];ll dfs(int pos,int flag,int lim){ if(pos<0) return 1; if(!lim&&dp[pos][flag]!=-1) return dp[pos][flag]; int up=lim? dig[pos]:9; int ans=0; for(int i=0;i<=up;++i) { if(i==4) continue; if(flag&&i==2) continue; ans+=dfs(pos-1,i==6,lim&&(i==up)); } if(!lim) dp[pos][flag]=ans; return ans;}ll get(ll a){ int len=0; while(a) { dig[len++]=(a%10); a/=10; } return dfs(len-1,0,1);}int main(){ memset(dp,-1,sizeof(dp)); ll n,m; while(scanf("%lld%lld",&n,&m)!=EOF) { if(n==0&&m==0) break; printf("%lld\n",get(m)-get(n-1)); } return 0;}
HDU 3555
链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555
题意:问在一个区间内有多少个数字出现过连续的49?
思路:和上道题基本相似,只不过问的是出现的,考虑的条件只有一个了.每次枚举判断前一位和当前位即可
#include <iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<math.h>using namespace std;typedef long long ll;ll dp[30][12][2];int dig[30];ll dfs(int pos, int pre,int flag,int limt){ if(pos<0) return flag; if(!limt&&dp[pos][pre][flag]!=-1) return dp[pos][pre][flag]; int up=limt? dig[pos]: 9; ll ans=0; for(int i=0;i<=up;i++) { ans+=dfs(pos-1,i,flag||(pre==4&&i==9),limt&&(i==up)); } if(!limt) dp[pos][pre][flag]=ans; return ans;}ll get(ll num){ int len=0; while(num) { dig[len++]=(num%10); num/=10; } return dfs(len-1,0,0,1);}int main(){ memset(dp,-1,sizeof(dp)); int T; scanf("%d",&T); while(T--) { ll a; scanf("%lld",&a); printf("%lld\n",get(a)); } return 0;}
CF55D:http://codeforces.com/problemset/problem/55/D
第一次碰到这个题是在17年陕西省赛的热身赛上。然后三个人都不会就直接GG。
题意:问在一串序列中,有多少个数可以被它每一个位数都整除?
思想:将问题可以转换为有多少个数可以被所有数位的LCM整除.(记着求LCM的时候要考虑0)
这里有个小技巧:因为这个数字会很大所以每次对它mod一个2520,因为(1-9)的最小公倍数是2520,所以每次mod2520 并不改变问题的结果。。
#include <iostream>#include<algorithm>#include<stdio.h>#include<string.h>using namespace std;typedef long long ll;const int mod=2520;int ls[mod+10];ll dp[20][mod+10][50];int dig[30];ll dfs(int pos,int sum,int lcm,int lim){ if(pos<0) return sum%lcm==0; if(!lim&&dp[pos][sum][ls[lcm]]!=-1) return dp[pos][sum][ls[lcm]]; int up=lim? dig[pos]:9; ll ans=0; for(int i=0;i<=up;++i) { if(i==0) ans+=dfs(pos-1,(sum*10+i)%mod,lcm,lim&&(i==up)); else ans+=dfs(pos-1,(sum*10+i)%mod,lcm*i/__gcd(lcm,i),lim&&(i==up)); } if(!lim) dp[pos][sum][ls[lcm]]=ans; return ans;}ll get(ll a){ int len=0; while(a) { dig[len++]=(a%10); a/=10; } return dfs(len-1,0,1,1);}int main(){ memset(dp,-1,sizeof(dp)); int cnt=0; for(int i=1;i<=mod;++i) { if(mod%i==0) ls[i]= (++cnt); } int T; scanf("%d",&T); while(T--) { ll l,r; scanf("%I64d%I64d",&l,&r); printf("%I64d\n",get(r)-get(l-1)); } return 0;}
阅读全文
0 0
- 数位DP HDU3555+CF55D+HDU2089
- hdu3555,hdu2089 数位dp
- [hdu2089&&hdu3555]数位DP
- hdu3555+cf55D 数位dp入门题
- hdu2089 & hdu3555 基础数位DP
- hdu2089||hdu3555简单数位DP
- [基础数位DP] HDU2089 不要62 HDU3555 Bomb
- 数位DP!!!(hdu3555 hdu2089 hdu5898 2016弱校10.5 I)
- 【数位DP】 hdu3555 Bomb
- 【hdu3555】【数位DP】Bomb
- 【数位DP】Bomb HDU3555
- hdu3555 Bomb 数位DP
- hdu3555数位dp
- 数位dp hdu3555
- HDU3555:Bomb(数位DP)
- hdu3555 Bomb (数位DP)
- HDU3555 Bomb 数位DP
- hdu3555 数位DP
- Problem D: 质心算法
- 问题 D: 年终奖金
- PCLK,VSYNC和HSYNC的关系
- 14. Longest Common Prefix
- Java 关于类型类、this.getClass()的理解
- 数位DP HDU3555+CF55D+HDU2089
- [LeetCode
- MySQL存储引擎
- 链表排序
- JAVA传入换行属性
- nyoj-20 吝啬的国度
- 搜索 G题
- LeetCode300. Longest Increasing Subsequence
- 微服务,微架构[八]springboot多环境切换profiles