CF833C Ever-Hungry Krakozyabra

一、題目

點此看題

二、解法

很暴力的一道題,直接數位dpdp應該是做不出來的。

沒辦法了,只能暴力,如果我們去枚舉生成數,本質上是這樣一個方程的整數解:x0+x1...+x9=18x_0+x_1...+x_9=18,情況數是C(27,9)4e6C(27,9)\approx 4e6,啊哈哈!只有4e64e6,果斷搜索。

考慮如何檢查,這是就可以用數位dpdp了,我們維護 是否達到下界//是否達到上界的標記,如果兩者均沒有,那就可以隨便填,滿足條件。否則就在範圍內枚舉當前位選的數,由於我們只會沿着上界//下界走,只會算1818次,複雜度是對的。

#include <cstdio>
#define int long long
int read()
{
    int x=0,flag=1;char c;
    while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
    while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*flag;
}
int n,ans,a[20],b[20],cnt[20];
void work(int *a,int x)
{
    n=0;
    while(x)
    {
        a[++n]=x%10;
        x/=10;
    }
}
int ask(int p,int l,int r)
{
    if(p==0 || l+r==0) return 1;
    int L=l?a[p]:0,R=r?b[p]:9;
    for(int i=L;i<=R;i++)
        if(cnt[i])
        {
            cnt[i]--;
            if(ask(p-1,l&(i==L),r&(i==R)))
            {
                cnt[i]++;
                return 1;
            }
            cnt[i]++;
        }
    return 0;
}
void dfs(int p,int s)
{
    if(p==9)
    {
        cnt[p]=s;
        ans+=ask(n,1,1);
        return ;
    }
    for(int i=0;i<=s;i++)
    {
        cnt[p]=i;
        dfs(p+1,s-i);
    }
}
signed main()
{
    work(a,read());
    work(b,read());
    dfs(0,n);
    printf("%lld\n",ans);
}
發佈了288 篇原創文章 · 獲贊 14 · 訪問量 8902
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章