[POJ 3252] Round Numbers

[题目链接]

          http://poj.org/problem?id=3252

[算法]

         数位DP

         f[i][j][k]表示在二进制表示下第1位为i,共有j位,其中共有k位为0

         实现时需注意细节!

[代码]

          

#include <algorithm>  
#include <bitset>  
#include <cctype>  
#include <cerrno>  
#include <clocale>  
#include <cmath>  
#include <complex>  
#include <cstdio>  
#include <cstdlib>  
#include <cstring>  
#include <ctime>  
#include <deque>  
#include <exception>  
#include <fstream>  
#include <functional>  
#include <limits>  
#include <list>  
#include <map>  
#include <iomanip>  
#include <ios>  
#include <iosfwd>  
#include <iostream>  
#include <istream>  
#include <ostream>  
#include <queue>  
#include <set>  
#include <sstream>  
#include <stdexcept>  
#include <streambuf>  
#include <string>  
#include <utility>  
#include <vector>  
#include <cwchar>  
#include <cwctype>  
#include <stack>  
#include <limits.h> 
using namespace std;

long long S,E;
int f[10][50][50];

inline void dp()
{
        int i,j;
        f[1][1][0] = f[0][1][1] = 1;
        for (i = 1; i < 31; i++)
        {
                for (j = 0; j <= i; j++) 
                {
                        f[0][i + 1][j + 1] += f[0][i][j] + f[1][i][j];
                        f[1][i + 1][j] += f[0][i][j] + f[1][i][j];
                } 
        }
}
inline int calc(int x)
{
        int i,j,len = 0,cnt = 0;
        int a[50];    
        int ret = 0;
        memset(a,0,sizeof(a));
        while (x)
        {
                a[++len] = x & 1;
                x >>= 1;        
        }    
        reverse(a + 1,a + len + 1);
        for (i = 1; i < len; i++) 
        {
                for (j = (i + 1) / 2; j <= i; j++)
                {
                        ret += f[1][i][j];
                }
        }
        for (i = 2; i <= len; i++)
        {
                if (a[i] == 0) cnt++;
                if (a[i] == 1)
                {
                        for (j = (len + 1) / 2; j <= len; j++)
                                if (j >= cnt) ret += f[0][len - i + 1][j - cnt];
                }
        }
        return ret;
}

int main() 
{
        
        dp();
        scanf("%d%d",&S,&E);
        printf("%d\n",calc(E + 1) - calc(S));
        
        return 0;
    
}

猜你喜欢

转载自www.cnblogs.com/evenbao/p/9368811.html