您的位置:首页 > 其它

hdu 4734 F(x)

2016-03-03 20:02 239 查看
题目链接: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)。

然后用记忆化搜索。

#include <bits/stdc++.h>
using namespace std;
int numa[12], numb[12];
int p[12];
int dp[12][5000];
void init()
{
memset(dp, -1, sizeof(dp));
p[0] = 1;
for(int i = 1; i <= 10; i++) p[i] = p[i-1]*2;
}
int F(int x)
{
int cnt = 0;
while(x)
{
numa[cnt++] = x%10;
x /= 10;
}
int sum = 0;
for(int i = cnt-1; i >= 0; i--) sum += p[i]*numa[i];
return sum;
}

int A, B;
int dfs(int cur, int rest, int limit)
{
if(cur < 0)
{
if(rest >= 0) return 1;
else return 0;
}
if(!limit && dp[cur][rest] != -1) return dp[cur][rest];

int ret = 0;
int up = limit?numb[cur]:9;
for(int i = 0; i <= up; i++)
{
int nowrest = rest- i*p[cur];
if(nowrest < 0) continue;
ret += dfs(cur-1, nowrest, limit && i == up);
}
if(!limit) dp[cur][rest] = ret;
return ret;
}
int slove(int x)
{
int cnt = 0;
while(x)
{
numb[cnt++] = x%10;
x /= 10;
}
return dfs(cnt-1, F(A), 1);
}
int main()
{
init();
//  freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
int cast = 0;
while(T--)
{
cast++;
scanf("%d%d", &A, &B);
printf("Case #%d: %d\n", cast, slove(B));

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: