数位DP-要49-基础DP-hdu3555-四种方法
来源:互联网 发布:淘宝选品数据分析 编辑:程序博客网 时间:2024/06/04 19:56
问1-n范围内存在49的个数。
大致找了四种方法
1 我用的反向查找的方法;
2 多状态记录的方法(好难写。不过挺有借鉴意义)
3 另一个网上找的大神的代码。
4 递推。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>long long dp[100][2];int cnt[100];using namespace std;long long dfs(int len,bool status,bool limit){ if(len<0) return 1;//计数 if(!limit&&dp[len][status]!=-1) return dp[len][status]; int bow=0; long long res=0; bow=limit?cnt[len]:9; for(int i=0;i<=bow;i++) { if(status&&i==9) continue; res+=dfs(len-1,i==4,i==bow&&limit); } if(!limit)//如果在limit上,是另行计算的。其实也就只是1而已。 dp[len][status]=res; return res;}long long solve(long long m){ memset(dp,-1,sizeof(dp));//计数也是可以成0的 memset(cnt,0,sizeof(cnt)); int len=0; while(m) { cnt[len++]=m%10; m/=10; } return dfs(len,false,true); /*开头的设置也是特别有讲究*/}int main(){ long long m;int t; cin>>t; while(t--) { scanf("%lld",&m); long long l=solve(m); l--; printf("%lld\n",m-l); } return 0;}
#include <iostream>#include <string.h>//dp[i][j]表示位数是i,状态为j//pos表示当前的位数//status中0表示不含49,1表示上一位是4,2表示含49//limit表示当前位是否受限制using namespace std;int digit[30];long long dp[30][3];int prepare(long long x){ memset(digit,0,sizeof(digit)); int cnt=0; while(x) { digit[++cnt]=x%10; x/=10; } return cnt;}long long solve(int pos,int status,int limit){ if(pos<=0) return status==2; if(!limit&&dp[pos][status]!=-1) return dp[pos][status];//这里就是说比如257,那么当你计算过了0到99之后,100到199就可以直接调用了,而2这一位是有限制的,所以不能直接调用现成的,要到下面重新计算一下 long long ans=0; int num=limit?digit[pos]:9; for(int i=0;i<=num; i++) { int nstatus=status;//相当于else s=status; if(status==0&&i==4)//高位不含49,并且末尾不是4,现在末尾添加的是4返回状态1 nstatus=1; else if(status==1&&i!=4&&i!=9)//高位不含49,且末尾是4,现在末尾添加的不是4,返回状态0 nstatus=0; else if(status==1&&i==9)//高位不含49,且末尾是4,现在末尾添加9,返回状态2 nstatus=2; ans+=solve(pos-1,nstatus,limit&&i==num); } if(!limit) dp[pos][status]=ans; return ans;}int main(){ int T; long long n; ios::sync_with_stdio(false); cin>>T; while(T--) { memset(dp,-1,sizeof(dp)); cin>>n; int len=prepare(n); long long sum=solve(len,0,1); cout<<sum<<endl; } return 0;}
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> using namespace std; #define RI(x) scanf("%d",&x) #define PIN(x) printf("%d\n",x) typedef long long ll; const int N = 30; ll z[N] = {1}; int t; int bit[N]; ll dp[N][2], n; ll dfs(int len, bool is4, bool ismax) { if (len == 0) return 0; if (!ismax && dp[len][is4] >= 0) return dp[len][is4]; ll cnt = 0; int mmax = ismax ? bit[len] : 9; for (int i = 0; i <= mmax; i++) { if (is4 && i == 9) { cnt += ismax ? n % z[len-1] + 1 : z[len-1]; } else { cnt += dfs(len - 1, i == 4, ismax && bit[len] == i); } } return ismax ? cnt : dp[len][is4] = cnt; } ll solve(ll n) { int len = 0; while (n) { bit[++len] = n % 10; n /= 10; } bit[len + 1] = 0; return dfs(len, false, true); } int main() { memset(dp, -1, sizeof(dp)); for (int i = 1; i < N; i++) { z[i] = z[i - 1] * 10; } RI(t); while (t--) { scanf("%I64d", &n); printf("I64d\n", solve(n)); // cin >> n; // cout << solve(n) << endl; } return 0; }
递推
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;__int64 dp[25][3];void Init(){ memset(dp,0,sizeof(dp)); dp[0][0] = 1; int i; for(i = 1;i<=22;i++) { dp[i][0] = dp[i-1][0]*10-dp[i-1][1]; dp[i][1] = dp[i-1][0]; dp[i][2] = dp[i-1][2]*10+dp[i-1][1]; }}__int64 solve(__int64 n){ __int64 i,tem = n,len = 0,a[25],flag = 0,ans = 0; while(n) { a[++len] = n%10; n/=10; } a[len+1] = 0; for(i = len;i;i--) { ans+=dp[i-1][2]*a[i]; if(flag) ans+=dp[i-1][0]*a[i]; if(!flag && a[i]>4) ans+=dp[i-1][1]; if(a[i+1] == 4 && a[i] == 9) flag = 1; } return ans;}int main(){ int t; __int64 n; scanf("%d",&t); Init(); while(t--) { scanf("%I64d",&n); printf("%I64d\n",solve(n+1)); } return 0;}
0 0
- 数位DP-要49-基础DP-hdu3555-四种方法
- HDU3555 要49 数位DP
- hdu2089 & hdu3555 基础数位DP
- 【数位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
- hdu3555(数位DP)
- Hdu3555 - Bomb - 数位dp
- hdu3555 Bomb 数位dp
- hdu3555 Bomb(数位DP)
- HDU3555 Bomb 数位DP
- hdu 2602 Bone Collector
- Codeforces 469D Two Sets【思维+并查集】
- PAT 1003 乙等 (我要通过) c++
- trunk函数详解
- 求数组中的次大值
- 数位DP-要49-基础DP-hdu3555-四种方法
- MyBatis架构设计及源代码分析(一):MyBatis架构
- 用node.js写的http小爬虫
- 1010: "水仙花数"问题1
- 菜鸟学习Spring——SpringMVC注解版控制层重定向到控制层
- PHP中include()与require()的区别
- Asp.Net Core 连接MySQL
- POJ 2313
- 计算几何 基础知识~具体的图像解决方案前导知识