hdu 4734 F(x)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4734

题意:给出一个数x包含n位(AnAn-1An-2 ... A2A1),定义F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1。

给出两个数字A, B,求0-B的数字中,满足F(X) <= F(A)的数有多少个。

思路:先求出F(A),定义dp[cur][rest],表示当前搜索到第cur位,剩余可以使用的大小还有rest,初始剩余大小就是F(A)。

然后用记忆化搜索。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int numa[12], numb[12];
 4 int p[12];
 5 int dp[12][5000];
 6 void init()
 7 {
 8     memset(dp, -1, sizeof(dp));
 9     p[0] = 1;
10     for(int i = 1; i <= 10; i++) p[i] = p[i-1]*2;
11 }
12 int F(int x)
13 {
14     int cnt = 0;
15     while(x)
16     {
17         numa[cnt++] = x%10;
18         x /= 10;
19     }
20     int sum = 0;
21     for(int i = cnt-1; i >= 0; i--) sum += p[i]*numa[i];
22     return sum;
23 }
24 
25 int A, B;
26 int dfs(int cur, int rest, int limit)
27 {
28     if(cur < 0)
29     {
30         if(rest >= 0) return 1;
31         else return 0;
32     }
33     if(!limit && dp[cur][rest] != -1) return dp[cur][rest];
34     
35     int ret = 0;
36     int up = limit?numb[cur]:9;
37     for(int i = 0; i <= up; i++)
38     {
39         int nowrest = rest- i*p[cur];
40         if(nowrest < 0) continue;
41         ret += dfs(cur-1, nowrest, limit && i == up);
42     }
43     if(!limit) dp[cur][rest] = ret;
44     return ret;
45 }
46 int slove(int x)
47 {
48     int cnt = 0;
49     while(x)
50     {
51         numb[cnt++] = x%10;
52         x /= 10;
53     }
54     return dfs(cnt-1, F(A), 1);
55 }
56 int main() 
57 {
58     init();
59   //  freopen("in.txt", "r", stdin);
60     int T;
61     scanf("%d", &T);
62     int cast = 0;
63     while(T--)
64     {
65         cast++;
66         scanf("%d%d", &A, &B);
67         printf("Case #%d: %d\n", cast, slove(B));
68         
69     }
70     return 0;
71 }

 

posted @ 2016-03-03 20:02  下周LGD该赢了吧  阅读(174)  评论(0编辑  收藏  举报