lightoj 1032 二进制的dp

题目链接:http://lightoj.com/volume_showproblem.php?problem=1032

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;


const int maxn = 33;
const int INF  = 0x3f3f3f;

long long  dp[maxn];
int sum[9] = {0,0,0,1,1,1,2,4,4};
long long int N;

inline long long res(int i){
    return (1<<i) + (1<<(i-1));
}

int main()
{
    freopen("E:\acm\input.txt","r",stdin);
    dp[2] = 1;
    for(int i=3;i<=31;i++){
        dp[i] = 2*dp[i-1] + (1<<(i-2));
    }
    int T;
    cin>>T;
    for(int cas=1;cas<=T;cas++){
        cin>>N;
        printf("Case %d: ",cas);
        if(N <= 8){
            printf("%d
",sum[N]);
            continue;
        }
        long long ans = 0;
        for(int i=30;i>=3;i--){
            long long temp = 1<<i;
            if(N >= temp){
               ans += dp[i];
               long long diff = N - res(i);
               if(diff >= 0){  //这个地方没有加等号WA了两次。
                 ans += diff + 1;
               }
               N -= temp;
            }
            if(N == 0) break;
        }
        cout<<ans+sum[N]<<endl;
    }
}
View Code
原文地址:https://www.cnblogs.com/acmdeweilai/p/3304049.html