zoukankan      html  css  js  c++  java
  • HDU 4734--基础数位dp(递推)

    以前成都赛区的题目。。

    http://acm.hdu.edu.cn/showproblem.php?pid=4734

    题意很明显,就是有一个F(x)的函数,然后给你一个a和b求出在0~b中有多少小于等于F(a)的,

    预处理出来dp[i][j][k]中有多少小于等于k的。。这里采用递推。。因为我太弱了。递归总是写错。。还需慢慢加深理解。。

    PS.代码很丑。。还是推荐递归。。实在不会递推也可以。。蒟蒻加油!

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    int dp[12][10][10000];
    int p[11]={1,2,4,8,16,32,64,128,256,512,1024};
    
    int init(){
        for(int j=0;j<10;j++)
            for(int k=0;k<5100;k++){
                dp[1][j][k]=(k>j?j+1:k+1);
            }
        for(int i=2;i<=10;i++){
            for(int k=0;k<5100;k++) dp[i][0][k]=dp[i-1][9][k];
            for(int j=1;j<10;j++){
                for(int k=0;k<5100;k++){
                    if(k-j*p[i-1]>=0)
                        dp[i][j][k]=dp[i][0][k-j*p[i-1]]+dp[i][j-1][k];
                    else
                        dp[i][j][k]=dp[i][j-1][k];
                }
            }
        }
    }
    
    int num[20];
    
    int cal(int x,int lim){
        int cnt=1;
        while(x){
            num[cnt++]=x%10;
            x/=10;
        }
        int ret=0,k=0,idx=1;
        for(int i=1;i<cnt;i++)
            if(num[i]==0)
                ++idx;
            else
                break;
        for(int i=cnt-1;i>0;i--){
            if(num[i]==0) continue;
            if(lim-k>=0)
                ret+=dp[i][num[i]-1][lim-k];
            else
                break;
            if(i==idx&&p[i-1]*num[i]<=lim-k)
                ret+=1;
            k+=p[i-1]*num[i];
        }
        return ret;
    }
    
    int F(int x){
        int ret=0;
        int cnt=0;
        while(x){
            ret+=p[cnt]*(x%10);
            x/=10;
            cnt++;
        }
        return ret;
    }
    
    int main()
    {
        int t;
        cin>>t;
        init();
        int cas=1;
        while(t--){
            int a,b;
            cin>>a>>b;
            int lim=F(a);
            if(lim==0||b==0){
                cout<<"Case #"<<cas++<<": "<<1<<endl;
                continue;
            }
            cout<<"Case #"<<cas++<<": "<<cal(b,lim)<<endl;
        }
        return 0;
    }
    



  • 相关阅读:
    在tmux中如何复制文本并粘贴到某处?
    linux下的用户密码文件/etc/shadow
    linux下openssl命令解析
    第 27 章 CSS 传统布局[下]
    第 27 章 CSS 传统布局[上]
    第 26 章 CSS3 动画效果
    第 25 章 CSS3 过渡效果
    第 24 章 CSS3 变形效果[下]
    第 23 章 CSS3 边框图片效果
    第 22 章 CSS3 渐变效果
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672565.html
Copyright © 2011-2022 走看看