zoukankan      html  css  js  c++  java
  • poj3252(数位dp)(模板)

    题目链接:https://vjudge.net/problem/POJ-3252

    题意:求[l,r]之间的Round Number数,RN数即化为二进制后0的个数不少于1的个数的数。

    思路:之前用组合数求写过,最近学数位dp,又用数位dp来写一次。用dp[pos][n0][n1]表示长为pos+1的数(我从0开始定义的),之前已经有n0个0和n1个1的前提下RN数有多少,用lead表示是否前导0,最后的递归终止条件为if(pos==-1) return n0>=n1。

    AC代码:

    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int a[35],dp[35][35][35];
    
    int dfs(int pos,int n0,int n1,bool lead,bool limit){
        if(pos==-1) return n0>=n1;
        if(!limit&&!lead&&dp[pos][n0][n1]!=-1) return dp[pos][n0][n1];
        int up=limit?a[pos]:1,tmp=0;
        for(int i=0;i<=up;++i){
            if(lead){
                if(!i) tmp+=dfs(pos-1,n0,n1,lead&&!i,limit&&i==a[pos]);
                else tmp+=dfs(pos-1,n0,n1+1,lead&&!i,limit&&i==a[pos]);
            }
            else{
                if(!i) tmp+=dfs(pos-1,n0+1,n1,lead&&!i,limit&&i==a[pos]);
                else tmp+=dfs(pos-1,n0,n1+1,lead&&!i,limit&&i==a[pos]);
            }
        }
        if(!limit&&!lead) dp[pos][n0][n1]=tmp;
        return tmp;
    }
    
    int solve(int x){
        int pos=0;
        while(x){
            a[pos++]=x%2;
            x/=2;
        }
        return dfs(pos-1,0,0,true,true);
    }
    
    int main(){
        memset(dp,-1,sizeof(dp));
        int l,r;
        scanf("%d%d",&l,&r);
        printf("%d",solve(r)-solve(l-1));
        return 0;
    }
  • 相关阅读:
    网络设备安全需求规格
    web安全法则
    Write Hole 问题
    如何同步master的代码到fork分支代码
    Self assignment
    Uninitialized scalar variable
    Operands of different size in bitwise operation
    Insecure Compiler Optimization
    negative array index read
    Unintended sign extension
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10763022.html
Copyright © 2011-2022 走看看