HDU3555Bomb(记忆化搜索)
2015-07-16 20:37
411 查看
题目与不要62相似,数位dp
[code]#include <map> #include <set> #include <stack> #include <queue> #include <cmath> #include <ctime> #include <vector> #include <cstdio> #include <cctype> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define INF 0x3f3f3f3f #define inf -0x3f3f3f3f #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define mem0(a) memset(a,0,sizeof(a)) #define mem1(a) memset(a,-1,sizeof(a)) #define mem(a, b) memset(a, b, sizeof(a)) typedef long long ll; ll dp[25][3]; //dp[i][0] 有i位且都不含49 //dp[i][1] 有i位且第i位为9 //dp[i][2] 有i位且都含49 void init(){ mem0(dp); dp[0][0]=1; for(int 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]; // cout<<"PPPP"<<i<<"PPPP"<<dp[i][0]<<"PPPP"<<dp[i][1]<<"PPP"<<dp[i][2]<<endl; } } __int64 solve(__int64 n){ int len=0,a[100]; while(n){ a[++len]=n%10; n/=10; } a[len+1]=0; __int64 ans=0; int flag=0; // for(int i=len;i>=1;i--) // cout<<"PPPP"<<a[i]<<endl; for(int i=len;i>=1;i--){ ans+=dp[i-1][2]*a[i]; if(flag) ans+=dp[i-1][0]*a[i]; //不要忘记乘以a[i]! if(!flag&&a[i]>4) ans+=dp[i-1][1]; if(a[i]==9&&a[i+1]==4) flag=1; } return ans; } int main(){ init(); int t; __int64 n; scanf("%d",&t); while(t--){ scanf("%I64d",&n); printf("%I64d\n",solve(n+1)); } return 0; }
[code]#include<bits/stdc++.h> using namespace std; typedef long long ll; int bit[100]; ll dp[20][3]; ll dfs(int p,int have,int lim){ int have_x; if(p<=0) return (have==2); if(lim!=1&&dp[p][have]!=-1) return dp[p][have]; int num= lim?bit[p]:9; //lim为0表示下一位没有限制,lim为1表示下一位有限制 ll ans=0; for(int i=0;i<=num;i++){ //have=0表示末尾既不是9也不是4 have_x=have; //have=1表示末尾是4 if(have==1&&i!=4) //have=2表示存在4和9连在一起 have_x=0; if(have==1&&i==9) have_x=2; if(have==0&&i==4) have_x=1; ans+=dfs(p-1,have_x,lim&&(num==i)); //printf("%d %d %I64d\n",p,i,ans); } if(!lim) dp[p][have]=ans; return ans; } void work(ll n){ int len=0; while(n){ bit[++len]=n%10; n/=10; } bit[len+1]=0; printf("%I64d\n",dfs(len,0,1)); } int main(){ ll n; int t; memset(dp,-1,sizeof(dp)); scanf("%d",&t); while(t--){ scanf("%I64d",&n); work(n); } return 0; }
相关文章推荐
- 转 C#对话框-打开和保存对话框
- Ubuntu下升级Git以及获取ssh keys的代码
- 算法导论 第十四章:数据结构的扩张
- Java反射机制
- pyQt不同窗体间的值传递(二)——使用信号槽机制
- C++之重载函数
- [主席树]HDOJ2665 && POJ2104 && POJ2761
- chapter18test2
- Spring基础---Spring源码解析以及入门
- [LeetCode]Combination Sum 2(!!!!!)
- Git 的origin和master分析
- Netbeans配合xdebug调试
- ASP.NET - (Session)后台登陆时,判断是不是已经登陆,如果不是,跳转回登陆页
- 习题2-5 分数化小数(decimal)
- 如何跟踪Entity Framework生成的SQL!
- Linux shell命令
- 数据库基础学习3-T-SQL语句
- 装饰器模式和代理模式区别
- Webform——验证控件
- 牢骚