HUD 4737 数位DP
来源:互联网 发布:mysql优化 编辑:程序博客网 时间:2024/06/07 20:57
题目链接
题意:给出F()函数 求在[0 - B]中有多少个数的F值小于F(A)
方法一:预处理 dp[i][j][st] 表示第i位为j 时 F值不大于st的个数
转移方程 dp[i][j][st] = ∑dp[i - 1][k][st - j * (2^(i -1))]
代码:
#include <cstdio>#include <iostream>#include <queue>#include <cstring>#define sf scanf#define pf printfusing namespace std;typedef long long LL;const int max_st = 9 * (2 << 10) + 50;int dp[15][10][max_st];void init_dp(){ memset(dp,0,sizeof(dp)); for(int i = 0;i < 10;++i) dp[1][i][i] = 1; for(int i = 0;i < 10;++i){ for(int j = i + 1;j < max_st;++j){ dp[1][i][j] += dp[1][i][j - 1]; } } for(int i = 2;i < 11;++i){ for(int j = 0;j < 10;++j){ int temp = j * (1 << (i - 1)); for(int p = temp;p < max_st;++p){ for(int k = 0;k < 10;++k){ dp[i][j][p] += dp[i - 1][k][p - temp]; } } } }}int digit[15];int solve(int A,int B){ int f_a = 0,temp = 1; while(A){ f_a = f_a + (A % 10)*temp;A = A / 10; temp <<= 1; } int len = 0; while(B){ digit[++len] = B % 10;B = B / 10;} int pre_sum = 0,ret = 0; for(int i = len;i;--i){ for(int j = 0;j < digit[i];++j){ ret += dp[i][j][f_a - pre_sum]; } pre_sum = pre_sum + digit[i] * (1 << (i - 1)); if(pre_sum > f_a) break; } return ret;}int main(){ init_dp(); int T,ca = 0,A,B; sf("%d",&T); while( T-- ){ sf("%d%d",&A,&B); pf("Case #%d: %d\n",++ca,solve(A,B + 1)); } return 0;}
方法二: DFS
代码:
#include <cstdio>#include <iostream>#include <queue>#include <cstring>#define sf scanf#define pf printfusing namespace std;typedef long long LL;const int max_st = 9 * (2 << 10) + 50;int dp[15][max_st];//dp[i][st] 第i位 f值不大于st的个数int digit[15];int f_a;int dfs(int i,int st,bool flag){ if(st < 0) return 0; if(!i) return dp[i][st] = !flag; if(!flag && ~dp[i][st]) return dp[i][st]; int ans = 0; int limit = flag ? digit[i] : 9; int temp = 1 << (i - 1) ; for(int j = 0;j <= limit;++j){ ans += dfs(i - 1,st - j * temp,flag && j == limit); } if(!flag) dp[i][st] = ans; return ans;}int solve(int A,int B){ int len = 0,fa_a = 0,temp = 1; while(B){ digit[++len] = B % 10;B = B / 10; } while(A) {fa_a = fa_a + (A % 10) * temp;A = A / 10;temp = temp << 1;} return dfs(len,fa_a,1);}int main(){ memset(dp,-1,sizeof(dp)); int T,ca = 0;sf("%d",&T); int A,B; while( T-- ){ sf("%d%d",&A,&B); pf("Case #%d: %d\n",++ca,solve(A,B + 1)); } return 0;}
0 0
- HUD 4737 数位DP
- hud 4722 Good Numbers(数位 DP)
- hud 2476 区间DP
- 数位dp
- 数位DP
- 数位DP
- 数位dp
- 数位dp
- 数位dp
- 数位DP
- 数位dp
- 数位DP
- 【数位DP】
- 数位DP
- 数位dp
- 数位dp
- 数位DP
- 数位DP
- javase 双色球选7球 红球在【1-36】之间,选出6个,且不能重复 篮球在【1-16】之间,选出1个
- 最长递增序列(hdu 5748)
- 环信(Android)设置头像和昵称的方法(最简单暴力的基于环信demo的集成)
- 我的IT备忘录
- Android中shape和selector的使用详解
- HUD 4737 数位DP
- Activiti(七)——排他网关(ExclusiveGateWay)
- 【杭电 5805 8.6 BC B NanoApe Loves Sequence】
- 基于tcl tk 的HyperGraph二次开发
- jquery animate step 实现 transform css3方法
- Android Studio设置自动编译工程
- POJ 2142
- codeforces 17D. Notepad 欧拉函数降幂
- Dom4j解析XML