HDU 4933 Miaomiao's Function 數位DP

這題第一感覺就是個數位DP,但是發現Answer太大,沒有辦法直接求。JAVA高精?但是JAVA太菜,寫不來o(╯□╰)o

這題的關鍵其實就是知道:x>0時,有f(x)== y。如果x%9 == 0,y == 9,否則y == x%9

如果確定了f(x),剩下的問題就很簡單了,關鍵是怎麼確定f(x),具體地說,怎麼判斷 f(x)==0?

我想了半天沒搞出來,結果看題解。。。。居然是MOD若干大質數,如果都爲0,說明f(x)爲0,否則爲9.。。。ORZ.........

//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<cctype>
#include<string>
#include<algorithm>
#include<iostream>
#include<ctime>
#include<map>
#include<set>
using namespace std;
#define MP(x,y) make_pair((x),(y))
#define PB(x) push_back(x)
typedef __int64 LL;
//typedef unsigned __int64 ULL;
/* ****************** */
const int INF = 100011122;
const double INFF = 1e100;
const double eps = 1e-8;
const int mod = 1000000009;
const int NN = 110;
const int MM = 5000010;
/* ****************** */

int a[NN];
LL dp[NN][2][3],sum[NN][2][3];
char s1[NN],s2[NN];

void INC(LL& a,LL b,LL MOD)
{
    a += b;
    if( a>= MOD) a -= MOD;
}
void INC_D(LL& a,LL b,LL MOD)
{
    a += b;
    a %= MOD;
    if(a < 0) a += MOD;
}

LL calc(char* ss,int del,LL MOD)
{
    int i, j, k, jj, k1, en, tol = 0;
    for(i = 0; ss[i]; i++)
    {
        a[++tol] = ss[i]-'0';
    }
    a[tol] -= del;
    if(tol==1 && a[tol]==-1)
        return 0;
    for(i = tol; i >= 1; i--)
    {
        if(a[i] < 0)
        {
            a[i] += 10;
            a[i-1] -= 1;
        }
    }

    memset(dp, 0, sizeof(dp));
    memset(sum, 0, sizeof(sum));

    dp[0][1][2] = 1;
    for(i = 0; i < tol; i++)
        for(j = 0; j < 2; j++)
            for(k = 0; k < 3; k++)
                if(dp[i][j][k])
                {
                    if(j==1)en = a[i+1];
                    else en = 9;
                    for(k1 = 0; k1 <= en; k1++)
                    {
                        jj = j&(k1==en);
                        if(k==2)
                        {
                            if(k1==0)
                                INC(dp[i+1][jj][2], dp[i][j][k], MOD);
                            else
                            {
                                INC(dp[i+1][jj][(i+1)%2], dp[i][j][k], MOD);
                            }
                        }
                        else
                        {
                            INC(dp[i+1][jj][k], dp[i][j][k], MOD);
                        }
                    }
                }

    for(i = 0; i < tol; i++)
        for(j = 0; j < 2; j++)
            for(k = 0; k < 3; k++)
                if(dp[i][j][k] || sum[i][j][k])
                {
                    if(j==1)en = a[i+1];
                    else en = 9;
                    for(k1 = 0; k1 <= en; k1++)
                    {
                        jj = j&(k1==en);
                        if(k==2)
                        {
                            if(k1==0)
                            {
                                //INC(dp[i+1][jj][2], dp[i][j][k], MOD);
                            }
                            else
                            {
                               // INC(dp[i+1][jj][(i+1)%2], dp[i][j][k], MOD);
                                INC(sum[i+1][jj][(i+1)%2], sum[i][j][k], MOD);
                                INC_D(sum[i+1][jj][(i+1)%2], dp[i][j][k]*k1, MOD);
                            }
                        }
                        else
                        {
                          //  INC(dp[i+1][jj][k], dp[i][j][k], MOD);
                            if((i+1)%2==k)
                            {
                                INC(sum[i+1][jj][k], sum[i][j][k], MOD);
                                INC_D(sum[i+1][jj][k], dp[i][j][k]*k1, MOD);
                            }
                            else
                            {
                                INC(sum[i+1][jj][k], sum[i][j][k], MOD);
                                INC_D(sum[i+1][jj][k], -dp[i][j][k]*k1, MOD);
                            }
                        }
                    }
                }
    LL ans = 0;
    for(j = 0; j < 2; j++)
        for(k = 0; k < 3; k++)
            INC(ans, sum[tol][j][k], MOD);
    return ans;
}

LL solve(char* s1,char* s2,LL MOD)
{
    LL t1 = calc(s1, 1, MOD);
    LL t2 = calc(s2, 0, MOD);
    return ((t2 - t1)%MOD + MOD)%MOD;
}

int main()
{
    int cas;
    LL f1, f2, f3, ans;
    scanf("%d",&cas);
    while(cas--)
    {
        scanf("%s%s",s1,s2);
        f1 = solve(s1, s2, 9);
        if(f1==0)
        {
            f2 = solve(s1, s2, 1000000007);
            f3 = solve(s1, s2, 1000000009);
            if(f2==0 && f3==0)
                ;
            else
                f1 = 9;
        }

        if(f1==0)
        {
            puts("Error!");
        }
        else
        {
            ans = solve(s1, s2, f1);
            printf("%I64d\n",ans);
        }
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章