HDU 3709 Balanced Number (数位DP+思维)【模板】
来源:互联网 发布:windows无法连接到cmcc 编辑:程序博客网 时间:2024/05/16 18:29
A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. More specifically, imagine each digit as a box with weight indicated by the digit. When a pivot is placed at some digit of the number, the distance from a digit to the pivot is the offset between it and the pivot. Then the torques of left part and right part can be calculated. It is balanced if they are the same. A balanced number must be balanced with the pivot at some of its digits. For example, 4139 is a balanced number with pivot fixed at 3. The torqueses are 4*2 + 1*1 = 9 and 9*1 = 9, for left part and right part, respectively. It's your job
to calculate the number of balanced numbers in a given range [x, y].
to calculate the number of balanced numbers in a given range [x, y].
20 97604 24324
10897
【题解】
这道题很经典,套路很深,为什么呢?因为题目是这样说的:判断一个数方法是以某一位为支点,左边的数乘以力矩的和等于右边的数乘以力矩的和,这句话很限制我们的思维(至少我是跳坑里了),所以我一直在考虑怎么同时表示左边的力矩和和右边的力矩和,试了好多写法都不对,后来看了下别人博客,发现更巧的方法,那就是支点选定以后,从左往右依次求力矩乘积的和:(当前位置-支点位置)*力矩,可以想象,支点左边单个的力矩乘积肯定是正的,所以支点左边一定是越加越大的,而到了支点右边,单个的力矩乘积一定是负的,所以这个值肯定是越来越小了,而我们只需要判断那个点使得力矩和为0就符合题意了,同时剪枝:如果力矩由正直接变负了,那再往后肯定也是负的,就不可能出现答案了,所以这时候直接剪掉,这会提高很多效率,最后还要注意要刨除0,00,000,0000这种情况,可以看到,这种情况的个数就是len-1个。
每次遍历不同支点位置,结果累加就是答案。
【AC代码】
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;typedef __int64 ll;ll dp[30][30][5000];ll m,n;int num[30];ll dfs(int pos,int zhi,int ju,bool limit)//依次是 当前位置 支点位置 力矩大小 上限情况{ if(pos < 0) return ju == 0 ;//组合完了就退出 if(ju < 0) return 0; //力矩由正直接变负 剪枝退出 if(!limit && dp[pos][zhi][ju]!=-1) return dp[pos][zhi][ju]; ll ans=0; int endi= limit ? num[pos]:9;// for(int i=0;i<=endi;++i) { int next_ju=ju; next_ju+=(pos-zhi)*i;//力矩乘积的和 ans+=dfs(pos-1,zhi,next_ju,limit && i==endi); } if(!limit) dp[pos][zhi][ju]=ans; return ans;}ll solve(ll x){ int len=0; while(x) { num[len++]=x%10; x/=10; } ll ans=0; for(int i=0;i<len;++i)//遍历不同支点位置时的答案 { ans+=dfs(len-1,i,0,1); } return ans-(len-1);//出去0,00,000等的情况}int main(){ int t; memset(dp,-1,sizeof(dp)); scanf("%d",&t); while(t--) { scanf("%I64d %I64d",&m,&n); printf("%I64d\n",solve(n)-solve(m-1)); } return 0;}
阅读全文
0 0
- HDU 3709 Balanced Number (数位DP+思维)【模板】
- HDU 3709 Balanced Number(数位DP)
- hdu 3709 Balanced Number (数位dp)
- hdu 3709 Balanced Number(数位dp)
- HDU 3709 Balanced Number(数位DP)
- HDU 3709 Balanced Number (数位DP)
- HDU 3709 Balanced Number (数位dp)
- HDU-3709 Balanced Number (数位DP)
- HDU 3709 Balanced Number(数位dp)
- hdu 3709 Balanced Number (数位DP)
- HDU 3709 Balanced Number (数位DP)
- HDU 3709 Balanced Number(数位dp)
- HDU 3709 Balanced Number(数位DP)
- HDU 3709 Balanced Number(数位dp)
- HDU-3709 Balanced Number (数位dp)
- HDU 3709 Balanced Number(数位DP)
- 数位dp HDU 3709 Balanced Number
- Balanced Number - HDU 3709 数位dp
- wireshark监控android socket 通信
- BitmapShader渲染器:实现圆形图片
- 【DP】编辑距离
- 学习笔记20-经典面试题-求一个整数中1的个数
- 再谈java乱码:GBK和UTF-8互转尾部乱码问题分析
- HDU 3709 Balanced Number (数位DP+思维)【模板】
- JavaScriptSerializer中日期序列化问题解决方案
- 正序输入字符串,反序输出
- 删除空白页
- PBO
- 一个分号引发的血案,中文登录正常,英文登录挂掉
- 史上最全的Unity面试题(含答案)
- 从证书库导出PFX证书
- Jcrop组件上传图像并修改尺寸(SpringMVC+Spring+Mybatis)