zoukankan      html  css  js  c++  java
  • POJ 3252 Round Numbers(数位dp)

    题意:给定区间[l,r],l < r ,求区间中满足条件的正整数的个数:二进制表示下0的个数不少于1的个数。

    分析:f(x)表示<=x时满足条件的数的个数,所求问题即为f(r)-f(l-1)。x二进制表示下从高到低位为1,bi,bi-1, bi-2, b0, 长度为len, 那么f(x)可以这样求解:

    dp[i][j]表示从i~0位可以任意为0或1时,0的个数比1多j个情况,由于j可能为负数,所以这里方便处理,将j = 40表示0的个数和1的个数一样多。

    转移:dp[i][j] = sum{dp[i-1][j-1]+dp[i-1][j+1]}.

    1首先考虑长度<len的数,设长度l < len,由于首位一定为1,那么只需考虑剩下的l-1位任意选取时的情况;

    2考虑长度为len的数,首位一定为1,从次高位到低位一次考虑,如果bi为1,那么此位为0,之前的位数和1,bi+2, bi+1一样时,剩下的i-1,i-2, 0位便可任意选取。

    最后应该考虑x本身是否满足条件。

    代码:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <map>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cmath>
     7 #define pb push_back
     8 #define mp make_pair
     9 #define esp 1e-8
    10 #define lson   l, m, rt<<1
    11 #define rson   m+1, r, rt<<1|1
    12 #define sz(x) ((int)((x).size()))
    13 #define pb push_back
    14 #define in freopen("solve_in.txt", "r", stdin);
    15 #define bug(x) printf("Line : %u >>>>>>
    ", (x));
    16 #define inf 0x7f7f7f7f
    17 using namespace std;
    18 typedef long long LL;
    19 typedef map<int, int> MPS;
    20 typedef pair<int, int> PII;
    21 
    22 const int maxn = 33;
    23 int dp[maxn][100], dig[maxn];
    24 int solve(int x) {
    25     if(!x) return 0;
    26     int len = 0, ans = 0;
    27     while(x) {
    28         dig[len++] = x&1;
    29         x >>= 1;
    30     }
    31     int tot = 0;
    32     for(int i = len-1; i >= 0; i--) {
    33         if(i < len-1) {
    34             if(i-1 >= 0)
    35                 for(int j = 41; j < 100; j++)
    36                     ans += dp[i-1][j];
    37             if(dig[i]) {
    38                 if(i) {
    39                     for(int j = max(1, 40-tot-1); j < 100; j++)
    40                         ans += dp[i-1][j];
    41                 } else {
    42                     ans += (tot+1 >= 0);
    43                 }
    44             }
    45         }
    46         tot += dig[i] ? -1 : 1;
    47     }
    48     ans += (tot >= 0);
    49     return ans;
    50 }
    51 void pre() {
    52     dp[0][41] = 1;
    53     dp[0][39] = 1;
    54     for(int i = 1; i < maxn; i++)
    55         for(int j = 1; j < 100; j++) {
    56             dp[i][j] += dp[i-1][j+1]+dp[i-1][j-1];
    57         }
    58 }
    59 int main() {
    60     
    61     int l, r;
    62     pre();
    63     scanf("%d%d", &l, &r);
    64     cout << solve(r)-solve(l-1) << endl;
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    2js中的变量的数据类型
    hdu 1022火车进出站问题
    hdu 2412树形dp
    hdu2955 Robberies(java)
    IDEA导入HttpServlet包
    IDEA导入jar包
    Java工程打包成jar可执行文件
    Java基础笔记(一)——JDK、JRE、JVM
    正整数构成的线性表存放在单链表中,编写算法将表中的所有的奇数删除。(C语言)
    已知单链表的数据元素为整型数且递增有序,L为单链表的哨兵指针。编写算法将表中值大于X小于Y的所有结点的顺序逆置。(C语言)
  • 原文地址:https://www.cnblogs.com/rootial/p/4081026.html
Copyright © 2011-2022 走看看