HDU POJ 数位DP

来源:互联网 发布:权力的游戏山姆知乎 编辑:程序博客网 时间:2024/05/19 23:15

预处理求出所有答案,再根据具体数字求解,模板性较强。

DP版要想方程,所以还是记忆化搜索版容易,就是枚举每一位。

看http://blog.csdn.net/synapse7/article/details/21006265?utm_source=tuicoo的注释大概能懂。

递归版利用了bit从1计数,而参数按0计数。如

23则bit[1]=3,bit[2]=2,传len=2进去,然后for遍历bit[2]顺便把len-1递归下去,然后len=1时遍历bit[1]=3,继续传0进去,然后返回


HDU 3555 BOMB 不含49

#include <cstdio>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define CLR( a , x ) memset ( a , x , sizeof (a) )#define RE freopen("1.in","r",stdin)ll dp[25][3];         //dp[i][j]:i长度j情况//dp[i][0]  长度为i且不含49//dp[i][1]  长度为i不含49但以9开头//dp[i][2]  长度为i含49int bit[25];void init(){    CLR(dp,0);    dp[0][0] = 1;    for(int i=1;i<=20;i++)      //2^63次方在20位以内    {        dp[i][0] = dp[i-1][0]*10-dp[i-1][1];    //不含49*10-补上4组成的49        dp[i][1] = dp[i-1][0];                  //补上9        dp[i][2] = dp[i-1][2]*10+dp[i-1][1];    //已含49*10+补上4组成的49    }}int main(){    //RE;    int t;    ll n;    init();    cin>>t;    while(t--)    {        cin>>n;        n++;        int len = 0;        ll ans = 0;        while(n)        {            bit[++len] = n % 10;            n /= 10;        }        bit[len+1] = 0;        bool flag = false;        for(int i=len;i>=0;i--)        {            ans += dp[i-1][2]*bit[i];     //低位含49的*该位数字            if(flag)                ans += dp[i-1][0]*bit[i];  //组成49后就+=低位*该位            if(!flag && bit[i]>4)          //后一位是9,那么数字大于4的都包含49                ans += dp[i-1][1];            if(bit[i]==9 && bit[i+1]==4)    //组成49                flag = true;        }        cout<<ans<<endl;    }}

递归版

#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <set>#include <map>#include <stack>#include <queue>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define eps 10^(-6)#define Q_CIN ios::sync_with_stdio(false);#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define RE freopen("1.in","r",stdin);#define WE freopen("1.out","w",stdout);#define MOD 10009#define bug(x) cout<<#x<<":"<<(x)<<endl;#define sf(a) scanf("%d",&a)#define sff(a,b) scanf("%d%d",&a,&b)  #define sfff(a,b,c) scanf("%d%d%d",&a,&b,&c)  #define lson i<<1,l,m#define rson i<<1|1,m+1,rconst int maxn=25;const int maxm=1e6+5;const int inf = 0x3f3f3f3f;int bit[maxn];ll dp[maxn][2][2];ll dfs(int len,bool is4,bool ok49,bool ismax){    if(len<=0)    return ok49?1:0;    if(!ismax && dp[len][is4][ok49] != -1)    return dp[len][is4][ok49];    int pmax = ismax ? bit[len] : 9;    ll cnt = 0;    for (int i = 0; i <= pmax; ++i){        cnt += dfs(len - 1,i == 4,ok49 || (is4 && i == 9),ismax && i == pmax);    }    return ismax ? cnt : dp[len][is4][ok49] = cnt;}ll solve(ll n){    int cnt=0;    while(n){        bit[++cnt]=n%10;        n/=10;    }    return dfs(cnt,false,false,true);}int main(){    #ifndef ONLINE_JUDGE        freopen("1.in","r",stdin);    #endif    ll a,t;    memset(dp,-1,sizeof(dp));    cin>>t;    while(t--){        cin>>a;        cout<<solve(a)<<endl;    }    return 0;}


HDU 2089 不要62 不含4和相邻62的

#include <cstdio>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define Q_CIN ios::sync_with_stdio(false)#define CLR( a , x ) memset ( a , x , sizeof (a) )#define RE freopen("1.in","r",stdin)int dp[10][3];//dp[i][0]  长度为i,无不吉利且不以2开头//dp[i][1]  长度为i,无但以2开头//dp[i][2]  长度为i,有int bit[10];void init(){    CLR(dp,0);    dp[0][0] = 1;    for(int i=1;i<=10;i++)    {        dp[i][0] = dp[i-1][0]*9-dp[i-1][1]; //除4外的9个-后一位是2的情况        dp[i][1] = dp[i-1][0];              //直接加2        dp[i][2] = dp[i-1][2]*10+dp[i-1][1]+dp[i-1][0]; //原有的+加6的+加4的    }}int solve(int n){    int len = 0;    int ans = 0;    int tmp = n;    while(n)    {        bit[++len] = n % 10;        n /= 10;    }    bit[len+1] = 0;    bool flag = false;    for(int i=len;i>=0;i--)    {        ans += dp[i-1][2]*bit[i];        if(flag)            ans += dp[i-1][0]*bit[i];        if(!flag && bit[i]>6)            ans += dp[i-1][1];        if(!flag && bit[i]>2&&bit[i+1]==6)//62x           ans += dp[i][1]; //dp[i][1]        if(!flag && bit[i]>4)            ans += dp[i-1][0];        if((bit[i]==2 && bit[i+1]==6)||bit[i]==4)            flag = true;    }    return tmp-ans; //求没有不吉利的}int main(){//    RE;    int n,m;    init();    while(cin>>n>>m,m||n)    {        CLR(bit,0);        cout<<solve(m+1)-solve(n)<<endl;    //[n,m]=[1,m]-[1,n)    }    return 0;}



#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <set>#include <map>#include <stack>#include <queue>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define eps 10^(-6)#define Q_CIN ios::sync_with_stdio(false);#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define RE freopen("1.in","r",stdin);#define WE freopen("1.out","w",stdout);#define MOD 10009#define bug(x) cout<<#x<<":"<<(x)<<endl;#define sf(a) scanf("%d",&a)#define sff(a,b) scanf("%d%d",&a,&b)  #define sfff(a,b,c) scanf("%d%d%d",&a,&b,&c)  #define lson i<<1,l,m#define rson i<<1|1,m+1,rconst int maxn=10;const int maxm=1e6+5;const int inf = 0x3f3f3f3f;int bit[maxn];int dp[maxn][2];int dfs(int len,bool is6,bool ismax){    if(len==0)    return 1;    if(!ismax&&dp[len][is6]>=0)    return dp[len][is6];    int cnt=0,pmax=(ismax?bit[len]:9);    for (int i = 0; i <= pmax; ++i){        if(i==4||(is6&&i==2))   continue;        cnt+=dfs(len-1,i==6,ismax&&i==pmax);    }    return ismax?cnt:dp[len][is6]=cnt;}int solve(int n){    int cnt=0;    while(n){        bit[++cnt]=n%10;        n/=10;    }    return dfs(cnt,false,true);}int main(){    #ifndef ONLINE_JUDGE        freopen("1.in","r",stdin);    #endif    int a,b;    memset(dp,-1,sizeof(dp));    while(cin>>a>>b,a||b){        cout<<solve(b)-solve(a-1)<<endl;    }    return 0;}


POJ 3252 Round Numbers

求[x,y]区间内“二进制表示0比1多的数”的个数。处理前导0,前导0不算0。
dp[len][num0][num1]:长度为len,0的数量为num0,1数量为num1的个数
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define lson i<<1,l,m#define rson i<<1|1,m+1,rconst int maxn=50;const int maxm=1e6+5;const int inf = 0x3f3f3f3f;int bit[maxn];int dp[maxn][maxn][maxn];int dfs(int len,int num0,int num1,bool first,bool ismax){    if(len==0)    return num0>=num1?1:0;    if(!ismax && dp[len][num0][num1] != -1)    return dp[len][num0][num1];    int pmax = ismax ? bit[len] : 1;    int cnt = 0;    for (int i = 0; i <= pmax; ++i){        if(first){            if(i==0)                cnt += dfs(len-1,0,0,true,ismax&&i==pmax);            else                cnt += dfs(len-1,0,1,false,ismax&&i==pmax);        }else{            if(i==0)                cnt += dfs(len-1,num0+1,num1,false,ismax&&i==pmax);            else                cnt += dfs(len-1,num0,num1+1,false,ismax&&i==pmax);        }    }    return ismax ? cnt : dp[len][num0][num1] = cnt;}int solve(int n){    int cnt=0;    while(n){        bit[++cnt]=n%2;        n/=2;    }    return dfs(cnt,0,0,true,true);}int main(){    #ifndef ONLINE_JUDGE        freopen("1.in","r",stdin);    #endif    int a,t,b;    memset(dp,-1,sizeof(dp));    while(cin>>a>>b)        cout<<solve(b)-solve(a-1)<<endl;    return 0;}

弱校OJ 233数

#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <map>#include <queue>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define RE freopen("1.in","r",stdin);#define WE freopen("1.out","w",stdout);#define MOD 10009#define bug(x) cout<<#x<<":"<<(x)<<endl;#define lson i<<1,l,m#define rson i<<1|1,m+1,rconst int maxn=50;const int maxm=1e6+5;const int inf = 0x3f3f3f3f;int bit[maxn];ll dp[maxn][2][2][2];   //长度,是不是1,是不是23,是不是233ll dfs(int len,bool is2,bool is23,bool ok,bool ismax){    if(len<=0)    return ok?1:0;    if(!ismax && (dp[len][is2][is23][ok] != -1))    return dp[len][is2][is23][ok];    int pmax = ismax ? bit[len] : 9;    ll cnt = 0;    for (int i = 0; i <= pmax; ++i){        cnt += dfs(len - 1,i==2,is2&&i == 3,ok||(is23&&i==3),ismax && i == pmax);    }    return ismax ? cnt : dp[len][is2][is23][ok] = cnt;}ll solve(ll n){    int cnt=0;    while(n>0){        bit[++cnt]=n%10;        n/=10;    }    return dfs(cnt,false,false,false,true);}int main(){    // #ifndef ONLINE_JUDGE        // freopen("1.in","r",stdin);        // freopen("1.out","w",stdout);    // #endif    ll a,t;    memset(dp,-1,sizeof(dp));    cin>>t;    while(t--){        cin>>a;        cout<<solve(a)<<endl;    }    return 0;}


HDU 3652 B-number

#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <set>#include <map>#include <stack>#include <queue>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define eps 10^(-6)#define Q_CIN ios::sync_with_stdio(false);#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define RE freopen("1.in","r",stdin);#define WE freopen("1.out","w",stdout);#define MOD 10009#define bug(x) cout<<#x<<":"<<(x)<<endl;#define sf(a) scanf("%d",&a)#define sff(a,b) scanf("%d%d",&a,&b)  #define sfff(a,b,c) scanf("%d%d%d",&a,&b,&c)  #define lson i<<1,l,m#define rson i<<1|1,m+1,rconst int maxn=20;const int maxm=1e6+5;const int inf = 0x3f3f3f3f;int bit[maxn];ll dp[maxn][2][2][13]; //dp[i][j][k][k]:长度为i,是否以1结尾,有无13,模13的结果ll dfs(int len,bool end1,bool have13,int mod,bool ismax){    if(len==0)    return (!mod && have13);    if(!ismax && (dp[len][end1][have13][mod] != -1))    return dp[len][end1][have13][mod];    int pmax = ismax ? bit[len] : 9;    ll cnt = 0;    for (int i = 0; i <= pmax; ++i){        int tmod = (mod*10+i) % 13;        cnt += dfs(len-1,i==1,have13||(end1&&i==3),tmod,ismax && i == pmax);    }    return ismax ? cnt : dp[len][end1][have13][mod] = cnt;}ll solve(ll n){    int cnt=0;    while(n>0){        bit[++cnt]=n%10;        n/=10;    }    return dfs(cnt,false,false,0,true);}int main(){    ll a,t;    memset(dp,-1,sizeof(dp));    while(cin>>a){        cout<<solve(a)<<endl;    }    return 0;}





0 0
原创粉丝点击