$ SCOI2009 \強風$ $ $ DP桁の番号

\(ソル\)

デジタル\(DP \)定期的なルーチンの質問。

\(DP [I] [J ] \) 最初に高充填するためにローから表現\(iは\)位置と第1 \(iは\)の桁\(Jの\)プログラムの数。答えが\(ゾル(R)-sol(L + 1 )。\) ここで\(DP \)プロセスのは非常に簡単であり、一般的な計算誤差は以下である\(X \)\(ウィンディ\)ので、ここで簡単に、数このプロセス:

まず、前処理\(X \)\(CT \) \([I] \)を表し\(X \)のローからハイへ\が(私は\)の桁数であり、次いで、最初の答え累積安全状態\(AS = + \ _ {IのSUM = 1. 1} ^ {} -CT \ J = SUM {_ ^ 1} {F}。9 [I] [J] \)

次いで、第一第二の回答の累積的なセキュリティ状態、\(CT \)ビット(ローからハイへ)は、より少ない数である\([CT] \)\(AS = + \ sum_ {J} = ^ 1 {[CT] -1} F [CT] [J] \)

最後は答え統計的に危険な状態である、ほとんどのエラーが発生しやすい領域である。現在の最初に埋めたと\(私は\)ビットと\(私は\)する(CTの\を)\数字があると、\(のx \) のような、まず\(I-1 \)ビットの数は、2つの制限を充填している未満\([-Iは1] \)にある\は、([I] \)の間の差であります以上の絶対値に等しい\(2 \)

2件の脆弱性、1番号の場合がある上記の統計情報を検索します\(のx \)された\(風の強い\)数、それは判決のように、問題が解決され、少し考慮されますが。この問題をしてみましょうすると、現在と仮定することです記入\(Iは\) および\(ABS([I] -a [-I 1])<= 2 \) 次いで、次のものが充填されません\([-Iを1] \)次いで答えは、直接統計危険な状態を継続し、そしてません(\破る)\離れました。

\(コード\)

コード

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
int f[20][10],a[20];
il void init()
{
    go(i,0,9)f[1][i]=1;
    go(i,2,10)
    go(j,0,9)
    go(k,0,9)
    if(abs(j-k)>=2)f[i][j]+=f[i-1][k];
}
il int sol(Ri x)
{
    if(!x)return 0;
    Ri qvq=x,ct=0,ret=0;bool fl=1;
    while(qvq){a[++ct]=qvq%10;qvq/=10;}
    go(i,1,ct-1)
    go(j,1,9)ret+=f[i][j];
    go(i,1,a[ct]-1)ret+=f[ct][i];
    yes(i,ct,2)
    {
    go(j,0,a[i-1]-1)
    {
        if(abs(j-a[i])>=2)ret+=f[i-1][j];
    }
    if(abs(a[i]-a[i-1])<2){fl=0;break;}
    }
    return ret+fl;
}
int main()
{
    init();
    Ri l=read(),r=read();
    printf("%d\n",(sol(r)-sol(l-1)));
    return 0;
}

おすすめ

転載: www.cnblogs.com/forward777/p/11592770.html