数位DP 板子
来源:互联网 发布:玛丽莲曼森的衣服淘宝 编辑:程序博客网 时间:2024/05/22 18:23
//重点在于找到dp的状态, 每一维代表什么, 如何去筛选, 和前导零的影响.
贴一个常用板子: (记忆化搜索板子)
/** @Cain*/int dp[10][sta];int a[10];int dfs(int pos,int sta,bool limit) //limit 就是为了限制当前位是否是最高位.{ if(pos == 0) return 判断条件; //这个一般跟根据题目设的条件, 返回是否满足条件. if(!limit && dp[pos][sta] != -1) return dp[pos][sta];//当前位不是最高位, 并且被访问过,则直接更新. int up = limit ? a[pos] : 9; //如果数是213,则最高位不是2时就可以枚举到9,后面更新也可以直接 //记忆化搜索, 如果是2的话, 十位只能美枚举到1而不是9, 所以有个limit. int ans = 0; for(int i=0;i<=up;i++){ if() 操作; if() 操作; ....... ans += dfs(pos-1,sta判断,limit && i == a[pos]); } if(!limit) dp[pos][sta] = ans; return ans;}int cal(int x){ int pos = 1; while(x){ //一位一位的拆开. a[pos++] = x % 10; x /= 10; } return dfs(pos-1,0,true);}void solve(){ int n,m; //Fill(dp,-1); //这个放在外面是要根据题意来的, 若是这个数原本的性质, 则就可以放在外面.算一种优化. while(~scanf("%d%d",&n,&m)){ Fill(dp,-1); printf("%d\n",cal(m)-cal(n-1)); }}int main(){ int t = 1 ; //scanf("%d",&t); while(t--){ solve(); }}
现在举两个例子:
HDU – 2089 不要62
//数位DP入门题
AC Code
/** @Cain*/int dp[10][2]; //最大不超过10位,后面一维存前面那个数是不是6的状态.int a[10];int dfs(int pos,int sta,bool limit) //limit 就是为了限制当前位是否是最高位.{ if(pos == 0) return 1; if(!limit && dp[pos][sta] != -1) return dp[pos][sta]; int up = limit ? a[pos] : 9; int ans = 0; for(int i=0;i<=up;i++){ if(sta && i == 2) continue; //剔除不满足条件的. if(i == 4) continue; ans += dfs(pos-1,i==6,limit && i == a[pos]); } if(!limit) dp[pos][sta] = ans; return ans;}int cal(int x){ int pos = 1; while(x){ a[pos++] = x % 10; x /= 10; } return dfs(pos-1,0,true);}void solve(){ int n,m; Fill(dp,-1); //62 , 4 都是这些数本身的性质,所以可以放在while外面,这算是一种优化. while(~scanf("%d%d",&n,&m)){ if(n+m == 0) break; printf("%d\n",cal(m)-cal(n-1)); }}int main(){ int t = 1 ; //scanf("%d",&t); while(t--){ solve(); }}
HDU - 3652 B-number
//这个就用三维,dp[pos][mod][sta], pos代表当前位, mod代表前面剩下的余数, sta代表前一位有1还是有13还是都没有.
AC Code
/** @Cain*/int dp[15][15][3];int a[15];int dfs(int pos,int mod,int sta,bool limit) //limit 就是为了限制当前位是否是最高位.{ if(pos == 0) return (mod == 0 && sta == 2); //返回满足条件的. if(!limit && dp[pos][mod][sta] != -1) return dp[pos][mod][sta]; int up = limit ? a[pos] : 9; int ans = 0; int mod2,sta2; for(int i=0;i<=up;i++){ mod2 = (mod * 10 + i) % 13; //判断剩下的余数. sta2 = sta; //判断状态. if( sta == 1 && i == 3 ) sta2 = 2; //这个顺序放错就GG了,还是太弱了. else if( sta == 0 && i == 1 ) sta2 = 1; else if( sta == 1 && i != 1 ) sta2 = 0; ans += dfs(pos-1,mod2,sta2,limit && i == a[pos]); } if(!limit) dp[pos][mod][sta] = ans; return ans;}int cal(int x){ int pos = 1; while(x){ a[pos++] = x % 10; x /= 10; } return dfs(pos-1,0,0,true);}void solve(){ int n; Fill(dp,-1); while(~scanf("%d",&n)){ printf("%d\n",cal(n)-cal(0)); }}int main(){ int t = 1 ; //scanf("%d",&t); while(t--){ solve(); }}
阅读全文
0 0
- 数位DP 板子
- 数位DP学习 数位DP板子理解 CF55D解题报告
- hdu 6148 数位DP(板子 递增递减
- 数位dp
- 数位DP
- 数位DP
- 数位dp
- 数位dp
- 数位dp
- 数位DP
- 数位dp
- 数位DP
- 【数位DP】
- 数位DP
- 数位dp
- 数位dp
- 数位DP
- 数位DP
- C++程序员学Java系列之三三:如何使用迭代器
- Servlet工作流程
- c++ 重载操作符
- C++智能指针类似OC 内存引用计数实现
- spring boot 日志配置 logback-spring.xml
- 数位DP 板子
- HDU 2177 取(2堆)石子游戏
- jmeter中添加邮件观察仪
- 深入mysql "ON DUPLICATE KEY UPDATE" 语法的分析
- 前端笔记
- node异步API setTimeout,setInterval,process.nextTick,setImmediate详解
- 修改数据库密码
- 禁止微信浏览器调整字体
- 新手上手NVIDIA Jetson TX2 精贴(jetpack)