zoukankan      html  css  js  c++  java
  • hdu-4734 F(x)

    F(x)

    Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

    Problem Description
    For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight as F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1. Now you are given two numbers A and B, please calculate how many numbers are there between 0 and B, inclusive, whose weight is no more than F(A).
     
    (我还是翻译一下吧,不然哪天我自己都读不懂了(>_<))
    (对于一个有n位(这n位从高位到低位分别是AnAn-1An-2 ... A2A1)的十进制数,我们定义它的权值F(x)=An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1.现在给你两个数A,B,请计算[0,B]范围内有多少个权值<=F(A)的数)
     
    Input
    The first line has a number T (T <= 10000) , indicating the number of test cases.
    For each test case, there are two numbers A and B (0 <= A,B < 109)
     
    Output
    For every case,you should output "Case #t: " at first, without quotes. The t is the case number starting from 1. Then output the answer.
    Sample Input
    3
    0 100
    1 10
    5 100
    Sample Output
    Case #1: 1
    Case #2: 2
    Case #3: 13
    Recommend
    liuyiding   |   We have carefully selected several similar problems for you:  6216 6215 6214 6213 6212 
     
     
    Solution
    数位dp.
    dp[i][j]表示枚举到第i位,剩下的数位的权值和的限制为<=j
    很正常的一道数位dp.
    但是我很智障,Case的第一个大写打成了小写,莫名其妙地wa了,差点就开始对拍了.还是懒一点比较好,直接复制过来.
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int mi[13],dp[13][4611],oo[13];
    inline int read()
    {
    	register int ans=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)) {ans=ans*10+ch-'0';ch=getchar();}
    	return ans*f;
    }
    inline int reada()
    {
    	register int ans=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)) {ans=ans*2+ch-'0';ch=getchar();}
    	return ans*f;
    }
    int dfs(int wi,int cha,int lim)
    {
    	if(wi<1) return 1;
    	if(!lim&&dp[wi][cha]>-1) 
    	  return dp[wi][cha];
    	int o=lim? oo[wi]:9;
    	int ans=0;
    	for(int i=0;i<=o;i++)
    	{
    		if(i*mi[wi-1]>cha)
    		  break;
    		ans+=dfs(wi-1,cha-i*mi[wi-1],lim&&i==oo[wi]);
    	}
    	if(!lim) dp[wi][cha]=ans;
    	return ans;
    }
    int sol(int a,int b)
    {
    	int w=0;
    	while(b)
    	{
    		oo[++w]=b%10;
    		b/=10;
    	}
    	return dfs(w,a,1);
    }
    int main()
    {
    	int cas,a,b;       ///case重名 
    	cas=read();
    	mi[0]=1;
    	for(int i=1;i<=10;i++)
    	  mi[i]=2*mi[i-1];
    	memset(dp,-1,sizeof(dp));
    	for(int i=1;i<=cas;i++)
    	{
    		a=reada();b=read();
    		printf("Case #%d: ",i);
    		printf("%d
    ",sol(a,b));
    	}
    	return 0;
    }
  • 相关阅读:
    Ubuntu的启动配置文件grub.cfg(menu.lst)设置指南zz
    Qt/E客户端服务期间通信数据串行化
    开源协议简介BSD、 Apache Licence、GPL、LGPL、MIT转载
    Qt/E服务器到客户端的消息传递
    解决 Windows 和 Ubuntu 时间不一致的问题转载
    Qt/E服务器客户端架构
    Qt/E中的键盘设备管理
    Qt/E服务器客户端的通信机制
    解决 ssh 登录慢 转载
    c# 扩展方法奇思妙用变态篇一:由 Fibonacci 数列引出 “委托扩展” 及 “递推递归委托”
  • 原文地址:https://www.cnblogs.com/charlotte-o/p/7608270.html
Copyright © 2011-2022 走看看