loj 1032 数位dp

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

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

loj 1032 数位dp
 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

 

 

你可能感兴趣的:(dp)