loj 1032(数位dp)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25909

思路:好久没接触数位dp了=.=!,搞了这么久!一类记忆化搜索。

 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 using namespace std;

 6 #define FILL(a,b) memset(a,b,sizeof(a))

 7 typedef long long ll;

 8 

 9 ll dp[33][2][33];

10 int n,digit[33];

11 

12 

13 ll dfs(int pos,int pre,int sum,int doing)

14 {

15     if(pos==-1)return sum;

16     if(!doing&&dp[pos][pre][sum]!=-1)return dp[pos][pre][sum];

17     ll ans=0;

18     int end=doing?digit[pos]:1;

19     for(int i=0;i<=end;i++){

20         ans+=dfs(pos-1,i,sum+(pre==i&&i==1),doing&&i==end);

21     }

22     if(!doing)dp[pos][pre][sum]=ans;

23     return ans;

24 }

25 

26 ll Solve(int n)

27 {

28     int pos=0;

29     while(n){

30         digit[pos++]=(n&1);

31         n>>=1;

32     }

33     return dfs(pos-1,0,0,1);

34 }

35 

36 int main()

37 {

38     FILL(dp,-1);

39     int _case,t=1;

40     scanf("%d",&_case);

41     while(_case--){

42         scanf("%d",&n);

43         printf("Case %d: %lld\n",t++,Solve(n));

44     }

45     return 0;

46 }
View Code

 

你可能感兴趣的:(dp)