loj 1032 数位dp

来源:互联网 发布:java图书管理系统教程 编辑:程序博客网 时间:2024/06/02 05:15

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

思路:数位dp, 采用记忆化搜索, dp[pos][pre][have] 表示 pos处,前一位为pre, 当前有have个满足条件的状态。

 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6  7 long long dp[34][2][34]; 8 int n, digit[34]; 9 10 long long dfs(int pos, int pre, int have, int doing)11 {12     if (pos == -1) {13         return have;14     }15     if (!doing && dp[pos][pre][have] != -1) {16         return dp[pos][pre][have];17     }18     int end = doing ? digit[pos] : 1;19     long long ans = 0;20     for (int i = 0; i <= end; i++) {21         int nhave = have;22         if (pre == 1 && i == 1) {23             nhave++;24         }25         ans += dfs(pos - 1, i, nhave, i == end && doing);26     }27     if (!doing) {28         dp[pos][pre][have] = ans;29     }30     return ans;31 }    32 33 long long Solve(int n)34 {35     int pos = 0;36     while (n) {37         digit[pos] = n % 2;38         n /= 2;39         pos++;40     }41     return dfs(pos - 1, 0, 0, 1);42 }43 44 int main()45 {46     memset(dp, -1, sizeof(dp));47     int _case, t = 1;48     scanf("%d", &_case);49     while (_case--) {50         scanf("%d", &n);51         printf("Case %d: %lld\n", t++, Solve(n));52     }53     return 0;54 }55 56 57         
View Code

 

 

0 0
原创粉丝点击