题意:
给出F(x)的运算..F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1..其中A1为十进制数x的个位..A2为其十位....现在给出A,B求0~B中F(x)比F(A)小的个数
题解:
可以算出极限情况..999999999..得到的是4599..代表F(x)的值域是很小的..可以用数位DP来整..dp[t][y]代表长度为t的数..F(x)为y的个数..有了状态..转移小case了..不过数位DP是很容易错的..所以我还写了个暴力来对拍...
Program:
#include<iostream> #include<stack> #include<queue> #include<stdio.h> #include<algorithm> #include<string.h> #include<cmath> #define ll long long #define oo 1000000007 #define eps 1e-5 #define MAXN 100010 using namespace std; int dp[12][6000]; void PreWork() { int i,j,x,k,t=1; memset(dp,0,sizeof(dp)),dp[0][0]=1; for (i=1;i<=9;i++) { for (k=0;k<=4650;k++) for (j=0;j<=9;j++) dp[i][j*t+k]+=dp[i-1][k]; t<<=1; } } char c; int _2jie[15],num[9]; int input() { int x=0,i; do { c=getchar(); } while (c<'0' || c>'9'); while (c>='0' && c<='9') { x=x*10+c-'0'; c=getchar(); } _2jie[0]=1,num[0]=9; for (i=1;i<=10;i++) _2jie[i]=1<<i,num[i]=9*_2jie[i]+num[i-1]; return x; } char s[12]; int main() { int C,cases,A,B,P,t,ans, len,i,j,x,k; PreWork(); C=input(); for (cases=1;cases<=C;cases++) { A=input(),B=input(); ans=P=0,t=1; while (A) { P+=(A%10)*t; t*=2,A/=10; } //--------------------------- sprintf(s,"%d",B),len=strlen(s),t=0; for (i=len-1;i>=0;i--) { for (j=0;j<s[len-i-1]-'0';j++) for (x=0;x<=num[i];x++) //1!!! { if (j*_2jie[i]+x+t>P) break; ans+=dp[i][x]; } t+=(s[len-i-1]-'0')*_2jie[i]; if (t>P) break; } if (t<=P) ans++; //--------------------------- printf("Case #%d: %d\n",cases,ans); } return 0; }