zoukankan      html  css  js  c++  java
  • hdu3709 Balanced Number 数位DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3709

    题目大意就是求给定区间内的平衡数的个数

    要明白一点:对于一个给定的数,假设其位数为n,那么可以有n个不同的位作为支点,但每次只能有一个支点

    定义dp[len][pos][k],len表示当前还需处理的位数,pos表示当前的所选的支点的位置,k表示计算到当前的力矩之和(即从最高位到第len+1位)

    容易知道如果在某一个len>1的位置k已经小于0,那么就可以直接剪枝

    代码如下 :

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<cstdio>
     5 using namespace std;
     6 int bit[20];
     7 long long int dp[20][20][2000];
     8 long long  int x,y;
     9 
    10 
    11 long long int dfs(int len,int pos,int sum,bool flag )
    12 {
    13     long long int ans=0;
    14    if(len==0 ) return sum==0;
    15    if(sum<0) return 0;
    16    if(flag && dp[len][pos][sum]>=0) return dp[len][pos][sum];
    17 
    18    int tmp=flag?9:bit[len];
    19 
    20    for(int i=0;i<=tmp;i++)
    21    {
    22        int n_sum=sum;
    23        n_sum+=i*(len-pos);
    24        ans+=dfs(len-1,pos,n_sum,flag||i<tmp);
    25    }
    26    if(flag) dp[len][pos][sum]=ans;
    27    return ans;
    28 }
    29 long long int solve(long long int n)
    30 {
    31    int len=0;
    32    while(n) bit[++len]=n%10,n/=10;
    33    long long int ans=0;
    34    for(int i=1;i<=len;i++)
    35    {
    36       ans+=dfs(len,i,0,0);
    37    }
    38 
    39   return ans-(len-1);
    40    
    41 }
    42 int main()
    43 {
    44    int t;
    45    scanf("%d",&t);
    46    while(t--)
    47    {
    48        scanf("%64d %64d",&x,&y);
    49        memset(dp,-1,sizeof(dp));
    50        cout<<solve(y)<<endl;
    51     
    52    }
    53    return 0;
    54 }
  • 相关阅读:
    5.Makefile的原理及应用
    8.adr与ldr伪指令的区别
    6.反汇编的原理
    9.S5PV210的时钟系统
    1.No MBR错误
    4.交叉编译工具链的安装及使用
    Java角度制向弧度制转化
    Java小题,通过JNI调用本地C++共享库中的对应方法实现杨辉三角的绘制
    编译安装-PHP
    编译安装-MySQL5.5
  • 原文地址:https://www.cnblogs.com/xiaozhuyang/p/hdu3709.html
Copyright © 2011-2022 走看看