hdu 4734 F(x) (数位dp)

题目链接s 题意:将一个10进制数x按照2进制展开后得到的值设为f(x)…现在给出a,b(10^9)问【0,b】中满足f[x]<=f[a]的数的个数。 思路:先算出f[a]…然后我们发现f(x)最大也就10*2^10=10240.。。数组可以存下。。搞之。和上一道题类似。。我们不关心两个f函数的值具体是多少。。。只关心他们的相对大小情况。。所以还是可以合并成一个变量。。。然而我用两个变量为什么错了。。不懂==

错误代码(用两个变量分别记录)

  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年03月17日 星期四 21时30分57秒
  4File Name :code/hdu/4734.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33int a,b;
 34int digit[15],digita[15];
 35int fa;
 36int dp[10][110000];//dp[i][j]表示长度为i,f[x]为j的方案数...
 37int power[20];
 38
 39int cal( int n)
 40{
 41    ms(digita,0);
 42    int len = 0 ;
 43    while (n)
 44    {
 45	digita[++len] = n % 10;
 46	n /= 10 ;
 47    }
 48    int base = 1;
 49    int res = 0 ;
 50    for ( int i = 1 ; i <= len ; i ++)
 51    {
 52//	cout<<"digita:"<<digita[i]<<endl;
 53	res +=digita[i]*base;
 54	base*=2;
 55    }
 56
 57    return res;
 58}
 59
 60
 61int dfs(int pos,int sum,bool limit)
 62{
 63    if (pos==0)  return  sum<=fa;
 64    if (sum>fa) return 0; //sum只会越来越大。。所以这里可以减一下。。。
 65  //  if (sum+(power[pos+1]-1)*9<=fa) return 1; //如果后面的位置取最大仍然满足,可以提前就确定。减!
 66    if (!limit&&dp[pos][sum]!=-1) return dp[pos][sum];
 67
 68    int mx = limit?digit[pos]:9;
 69
 70    int res = 0  ;
 71    for ( int i = 0 ; i <= mx ; i++)
 72    {
 73       res+=dfs(pos-1,sum+i*power[pos],limit&&i==mx);
 74    }
 75
 76  //  if (!limit) dp[pos][sum] = res;
 77    return res;
 78}
 79int solve ( int n)
 80{
 81    ms(digit,0);
 82    int len = 0 ;
 83    while (n)
 84    {
 85	digit[++len] = n % 10;
 86	n /= 10;
 87    }
 88
 89    return dfs(len,0,true);
 90}
 91
 92void pre()
 93{
 94    power[1] = 1;
 95    for ( int i = 2 ; i <= 12 ; i++)
 96    {
 97	power[i] = power[i-1]*2;
 98    }
 99}
100int main()
101{
102	#ifndef  ONLINE_JUDGE 
103	freopen("code/in.txt","r",stdin);
104  #endif
105	pre();
106	int T;
107	cin>>T;
108	ms(dp,-1);
109	int cas = 0 ;
110	while (T--)
111	{
112	    scanf("%d %d",&a,&b);
113	    fa = cal(a);
114	    int ans = solve(b);
115	    printf("Case #%d: %d\n",++cas,ans);
116	}
117
118  #ifndef ONLINE_JUDGE  
119  fclose(stdin);
120  #endif
121    return 0;
122}

AC代码:

  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年03月18日 星期五 08时57分02秒
  4File Name :code/hdu/r4734.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33int digit[20];
 34int a,b;
 35int dp[11][11000];
 36int power[15];
 37int fa;
 38int cal( int n)
 39{
 40//    cout<<"n:"<<n;
 41    int base = 1;
 42    int res = 0 ;
 43    while (n)
 44    {
 45	res += (n)*base;
 46	base*=2;
 47	n/=10;
 48    }
 49//    cout<<" res:"<<res<<endl;
 50    return res;
 51}
 52
 53int dfs( int pos,int sum,bool limit)  //依然是只关心两个数的相对大小。。。而不关心他们具体是多少。。
 54{                                       //所以可以合并成一个变量。。。
 55//    cout<<"pos:"<<pos<<" sum:"<<sum<<endl;
 56    if (pos==0) return sum>=0;
 57    if (sum<0) return 0;
 58
 59    if (!limit&&dp[pos][sum]!=-1) return dp[pos][sum];
 60
 61    int mx = limit? digit[pos] : 9 ;
 62    int res = 0 ;
 63    for ( int i =  0 ; i <= mx ; i++)
 64    {
 65	res+=dfs(pos-1,sum-power[pos]*i,limit&&i==mx);
 66    }
 67    if (!limit) dp[pos][sum] = res;
 68    return res;
 69}
 70int solve ( int n )
 71{
 72    int len = 0 ;
 73    ms(digit,0);
 74    while (n)
 75    {
 76	digit[++len] = n % 10;
 77	n/=10;
 78    }
 79//    for ( int i = len ; i >=1 ;  i--) cout<<digit[i];
 80    return dfs(len,cal(a),true);
 81}
 82int main()
 83    {
 84	#ifndef  ONLINE_JUDGE 
 85	freopen("code/in.txt","r",stdin);
 86  #endif
 87
 88	power[1] = 1;
 89	for ( int  i = 2 ; i <= 12 ; i++) power[i] = power[i-1] * 2; //循环不小心从1开始。。。结果全0了。。。。2333
 90	int T;
 91	cin>>T;
 92	int cas = 0;
 93	ms(dp,-1);
 94	while (T--)
 95	{
 96	    scanf("%d %d",&a,&b);
 97	    fa = cal(a);
 98	    int ans = solve(b);
 99	    printf("Case #%d: %d\n",++cas,ans);
100
101	}
102
103  #ifndef ONLINE_JUDGE  
104  fclose(stdin);
105  #endif
106    return 0;
107}