HDU-4734 : F(x) [ Digit DP ]

HDU-4734 : F(X)  [Digit DP]

IDEA: Problem is asking for how many integers(x) are there in the range 0 to B, which have F(x) less than or equal to F(A).
Simply a digit dp with state "POS", "If we take any less digit" and "Tot sum for F(x)".
But, the main problem is that there are lot of test cases..So, to avoid clearing DP array for each testcases,
we only memorize two state POS & SUM, so that we have only one state which will be not memorized in each testcases.

CODE:
///==================================================///
/// HELLO WORLD !! ///
/// IT'S ME ///
/// BISHAL GAUTAM ///
/// [ bsal.gautam16@gmail.com ] ///
///==================================================///
#include<bits/stdc++.h>
#define X first
#define Y second
#define mpp make_pair
#define nl printf("\n")
#define SZ(x) (int)(x.size())
#define pb(x) push_back(x)
#define pii pair<int,int>
#define pll pair<ll,ll>
///---------------------
#define S(a) scanf("%d",&a)
#define P(a) printf("%d",a)
#define SL(a) scanf("%lld",&a)
#define S2(a,b) scanf("%d%d",&a,&b)
#define SL2(a,b) scanf("%lld%lld",&a,&b)
///------------------------------------
#define all(v) v.begin(),v.end()
#define CLR(a) memset(a,0,sizeof(a))
#define SET(a) memset(a,-1,sizeof(a))
#define fr(i,a,n) for(int i=a;i<=n;i++)
using namespace std;
typedef long long ll;
///==========CONSTANTS=============///
/// Digit 0123456789012345678 ///
#define MX 100005
#define inf 200000000
#define MD 1000000000LL
#define eps 1e-9
///===============================///

int ar[10];
int dp[10][9220];
int go(int p,int ch,int vl) {
if( p<0 ) return (vl>=0);
if( vl<0 ) return 0;
int &ret=dp[p][vl];
if(ch && ret!=-1) return ret;
int ans=0;
int mx=ar[p];
if(ch)mx=9;
for(int i=0; i<=mx; i++) {
ans+=go(p-1,ch||i<mx,vl-(i*(1<<p)));
}
return (ch?(ret=ans):ans);
}

int Solve(int nm,int vl) {
int n=0;
while(nm) {
ar[n++]=nm%10;
nm/=10;
}
return go(n-1,0,vl);
}

int F(int x) {
int sm=0,tw=1;
while(x) {
sm+=((x%10)*tw);
x/=10;
tw<<=1;
}
return sm;
}
int main() {
int tc,cs=1,i,j,k,a,b;
S(tc);
SET(dp);
while(tc--) {
S2(a,b);
int ans=Solve(b,F(a));
printf("Case #%d: %d\n",cs++,ans);
}
return 0;
}

Comments

Popular posts from this blog

HackerEarth: City and Campers 2 (DSU-UnionFind)

Two Pointers Technique & Binary Search For Beginners

Problem : Codeforces Round #406 (Div. 1) B [ Legacy ]( Dijakstra, Segment tree)