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函数的值具体是多少。。。只关心他们的相对大小情况。。所以还是可以合并成一个变量。。。然而我用两个变量为什么错了。。不懂==
错误代码(用两个变量分别记录)
/* ***********************************************
Author :111qqz
Created Time :2016年03月17日 星期四 21时30分57秒
File Name :code/hdu/4734.cpp
************************************************ */
1#include <cstdio>
2#include <cstring>
3#include <iostream>
4#include <algorithm>
5#include <vector>
6#include <queue>
7#include <set>
8#include <map>
9#include <string>
10#include <cmath>
11#include <cstdlib>
12#include <ctime>
13#define fst first
14#define sec second
15#define lson l,m,rt<<1
16#define rson m+1,r,rt<<1|1
17#define ms(a,x) memset(a,x,sizeof(a))
18typedef long long LL;
19#define pi pair < int ,int >
20#define MP make_pair
1using namespace std;
2const double eps = 1E-8;
3const int dx4[4]={1,0,0,-1};
4const int dy4[4]={0,-1,1,0};
5const int inf = 0x3f3f3f3f;
6int a,b;
7int digit[15],digita[15];
8int fa;
9int dp[10][110000];//dp[i][j]表示长度为i,f[x]为j的方案数...
10int power[20];
1int cal( int n)
2{
3 ms(digita,0);
4 int len = 0 ;
5 while (n)
6 {
7 digita[++len] = n % 10;
8 n /= 10 ;
9 }
10 int base = 1;
11 int res = 0 ;
12 for ( int i = 1 ; i <= len ; i ++)
13 {
14// cout<<"digita:"<<digita[i]<<endl;
15 res +=digita[i]*base;
16 base*=2;
17 }
return res;
}
1int dfs(int pos,int sum,bool limit)
2{
3 if (pos==0) return sum<=fa;
4 if (sum>fa) return 0; //sum只会越来越大。。所以这里可以减一下。。。
5 // if (sum+(power[pos+1]-1)*9<=fa) return 1; //如果后面的位置取最大仍然满足,可以提前就确定。减!
6 if (!limit&&dp[pos][sum]!=-1) return dp[pos][sum];
int mx = limit?digit[pos]:9;
1 int res = 0 ;
2 for ( int i = 0 ; i <= mx ; i++)
3 {
4 res+=dfs(pos-1,sum+i*power[pos],limit&&i==mx);
5 }
1 // if (!limit) dp[pos][sum] = res;
2 return res;
3}
4int solve ( int n)
5{
6 ms(digit,0);
7 int len = 0 ;
8 while (n)
9 {
10 digit[++len] = n % 10;
11 n /= 10;
12 }
return dfs(len,0,true);
}
1void pre()
2{
3 power[1] = 1;
4 for ( int i = 2 ; i <= 12 ; i++)
5 {
6 power[i] = power[i-1]*2;
7 }
8}
9int main()
10{
11 #ifndef ONLINE_JUDGE
12 freopen("code/in.txt","r",stdin);
13 #endif
14 pre();
15 int T;
16 cin>>T;
17 ms(dp,-1);
18 int cas = 0 ;
19 while (T--)
20 {
21 scanf("%d %d",&a,&b);
22 fa = cal(a);
23 int ans = solve(b);
24 printf("Case #%d: %d\n",++cas,ans);
25 }
1 #ifndef ONLINE_JUDGE
2 fclose(stdin);
3 #endif
4 return 0;
5}
AC代码:
/* ***********************************************
Author :111qqz
Created Time :2016年03月18日 星期五 08时57分02秒
File Name :code/hdu/r4734.cpp
************************************************ */
1#include <cstdio>
2#include <cstring>
3#include <iostream>
4#include <algorithm>
5#include <vector>
6#include <queue>
7#include <set>
8#include <map>
9#include <string>
10#include <cmath>
11#include <cstdlib>
12#include <ctime>
13#define fst first
14#define sec second
15#define lson l,m,rt<<1
16#define rson m+1,r,rt<<1|1
17#define ms(a,x) memset(a,x,sizeof(a))
18typedef long long LL;
19#define pi pair < int ,int >
20#define MP make_pair
1using namespace std;
2const double eps = 1E-8;
3const int dx4[4]={1,0,0,-1};
4const int dy4[4]={0,-1,1,0};
5const int inf = 0x3f3f3f3f;
6int digit[20];
7int a,b;
8int dp[11][11000];
9int power[15];
10int fa;
11int cal( int n)
12{
13// cout<<"n:"<<n;
14 int base = 1;
15 int res = 0 ;
16 while (n)
17 {
18 res += (n)*base;
19 base*=2;
20 n/=10;
21 }
22// cout<<" res:"<<res<<endl;
23 return res;
24}
1int dfs( int pos,int sum,bool limit) //依然是只关心两个数的相对大小。。。而不关心他们具体是多少。。
2{ //所以可以合并成一个变量。。。
3// cout<<"pos:"<<pos<<" sum:"<<sum<<endl;
4 if (pos==0) return sum>=0;
5 if (sum<0) return 0;
if (!limit&&dp[pos][sum]!=-1) return dp[pos][sum];
1 int mx = limit? digit[pos] : 9 ;
2 int res = 0 ;
3 for ( int i = 0 ; i <= mx ; i++)
4 {
5 res+=dfs(pos-1,sum-power[pos]*i,limit&&i==mx);
6 }
7 if (!limit) dp[pos][sum] = res;
8 return res;
9}
10int solve ( int n )
11{
12 int len = 0 ;
13 ms(digit,0);
14 while (n)
15 {
16 digit[++len] = n % 10;
17 n/=10;
18 }
19// for ( int i = len ; i >=1 ; i--) cout<<digit[i];
20 return dfs(len,cal(a),true);
21}
22int main()
23 {
24 #ifndef ONLINE_JUDGE
25 freopen("code/in.txt","r",stdin);
26 #endif
1 power[1] = 1;
2 for ( int i = 2 ; i <= 12 ; i++) power[i] = power[i-1] * 2; //循环不小心从1开始。。。结果全0了。。。。2333
3 int T;
4 cin>>T;
5 int cas = 0;
6 ms(dp,-1);
7 while (T--)
8 {
9 scanf("%d %d",&a,&b);
10 fa = cal(a);
11 int ans = solve(b);
12 printf("Case #%d: %d\n",++cas,ans);
}
1 #ifndef ONLINE_JUDGE
2 fclose(stdin);
3 #endif
4 return 0;
5}