POJ 3252 数位DP

来源:互联网 发布:java支付平台开发demo 编辑:程序博客网 时间:2024/06/05 08:11

点击打开链接

题意:问给定区间内的数的二进制状态下0的个数大于等于1的个数的数量

思路:开两个变量记录0和1的个数即可,然后应该将数分解成二进制

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const ll INF=0x3f3f3f3f3f3f3f3fll;const int maxn=5010;int dig[40];ll dp[40][30][30];ll dfs(int pos,int lim,int num0,int num1,int flag){    if(pos<0){        if(flag) return 0;        else if(num0>=num1) return 1;        else return 0;    }    if(!lim&&dp[pos][num0][num1]!=-1) return dp[pos][num0][num1];    int las=lim?dig[pos]:1;    ll ret=0;    for(int i=0;i<=las;i++){        if(flag&&i==0) ret+=dfs(pos-1,lim&&(i==las),0,0,1);        else if(i==0) ret+=dfs(pos-1,lim&&(i==las),num0+1,num1,0);        else ret+=dfs(pos-1,lim&&(i==las),num0,num1+1,0);    }    if(!lim) dp[pos][num0][num1]=ret;    return ret;}ll slove(ll n){    if(n==0) return 0;    int len=0;    while(n){        dig[len++]=n%2;        n/=2;    }    return dfs(len-1,1,0,0,1);}int main(){    memset(dp,-1,sizeof(dp));    ll n,m;    while(scanf("%I64d%I64d",&n,&m)!=-1){        printf("%I64d\n",slove(m)-slove(n-1));    }    return 0;}

0 0
原创粉丝点击