标签:一个 优化 start rom lap mem 暴力枚举 include title
(https://www.pixiv.net/member_illust.php?mode=medium&illust_id=65608478)
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).
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)
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.
30 1001 105 100
Case #1: 1Case #2: 2Case #3: 13
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 int f[11][10000],a,b,len,orz[11],sum,mi[11]; 7 8 int dfs(int pos,int pre,bool limit){ 9 if(pos==0){ 10 if(pre<=sum) return 1; 11 return 0; 12 } 13 if((!limit)&&f[pos][sum-pre]!=-1) return f[pos][sum-pre]; 14 int st=limit?orz[pos]:9; 15 int ans=0; 16 for(int i=0;i<=st;i++) 17 if(pre+i*mi[pos]<=sum) ans+=dfs(pos-1,pre+i*mi[pos],limit&&i==st); 18 if(!limit) f[pos][sum-pre]=ans; 19 return ans; 20 } 21 int main(){ 22 memset(f,-1,sizeof(f)); 23 mi[1]=1; 24 for(int i=2;i<=10;i++) mi[i]=mi[i-1]*2; 25 int t; 26 scanf("%d",&t); 27 for(int k=1;k<=t;k++){ 28 scanf("%d%d",&a,&b); 29 sum=0; 30 for(int i=a,j=1;i;i/=10,j++) sum+=mi[j]*(i%10);//printf("sum=%d\n",sum); 31 for(len=0,b;b;b/=10) orz[++len]=b%10; 32 printf("Case #%d: %d\n",k,dfs(len,0,1)); 33 } 34 return 0; 35 }
标签:一个 优化 start rom lap mem 暴力枚举 include title
原文地址:http://www.cnblogs.com/LinnBlanc/p/7780555.html