數位dp

不要62和帶4的值 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long ll;

int data[20];
ll dp[25][2];

ll dfs(int pos, int h, int sta, bool limit)  //limit爲臨界判斷,pos爲當前位數(從高到低)其他值根據題意設置
{
    if(pos == 0) return 1;

    if(!limit && dp[pos][sta]!=-1) return dp[pos][sta];  //一般不變

    int up = limit ? data[pos] : 9;  //當前位最大值
    ll ans = 0;

    for(int i = 0; i <= up; i++)
    {
        if(i==4) continue;  //不滿足的條件
        if(h==6&&i==2) continue;
        ans += dfs(pos - 1, i, i==6, i == data[pos] && limit);  //遞歸
    }

    if(!limit) dp[pos][sta] = ans;  //記憶化
    return ans;
}
//將每一位存起來
ll solve(ll n)
{
    int pos = 0;
    while(n)
    {
        data[++pos] = n % 10;
        n /= 10;
    }
    return dfs(pos , 0, 1, true);
}

int main()
{
    ll a, b;
    int cnt = 0;
    memset(dp, -1, sizeof(dp));
    while(~scanf("%lld %lld", &a, &b)&&(a||b))
    {
        printf("%lld\n", solve(b) - solve(a - 1));
    }
    return 0;
}

只要帶49的數

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long ll;

int data[20];
ll dp[25][2][2];

ll dfs(int pos, int h, int sta, bool limit)
{
    if(pos == 0)
        return h;

    if(!limit && dp[pos][h][sta]!=-1)
        return dp[pos][h][sta];

    int up = limit ? data[pos] : 9;
    ll ans = 0;

    for(int i = 0; i <= up; i++)
    {
        if(sta&&i==9) 
            ans += dfs(pos-1,1,0,i==data[pos]&&limit);   //符合條件
        else
            ans+=dfs(pos-1,h,i==4,i==data[pos]&&limit);  //不符合條件
    }

    if(!limit)
        dp[pos][h][sta] = ans;
    return ans;
}

ll solve(ll n)
{
    int pos = 0;
    while(n)
    {
        data[++pos] = n % 10;
        n /= 10;
    }
    return dfs(pos, 0, 0, true);
}

int main()
{
    ll a, n;
    scanf("%lld",&n);
    int cnt = 0;
    memset(dp, -1, sizeof(dp));
    while(n--)
    {
        scanf("%lld", &a);
        printf("%lld\n", solve(a));
    }
    return 0;
}

能被13整除並帶13的數字

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long ll;

int data[20];
ll dp[25][2][20][10];

ll dfs(int pos, int h,int k, int sta, bool limit)  k爲當前數取餘13的值,又a%mod+b%mod=(a+b)%mod可以驗證方法正確
{
    if(pos == 0)
        return h==1&&k==0;
    if(!limit && dp[pos][h][k][sta]!=-1)
        return dp[pos][h][k][sta];
    int up = limit ? data[pos] : 9;
    ll ans = 0;
    for(int i = 0; i <= up; i++)
    {
        if(sta==1&&i==3)
            ans+= dfs(pos-1,1,(k*10+i)%13,i,i==data[pos]&&limit);  //判斷是否含13
        else
            ans+=dfs(pos-1,h,(k*10+i)%13,i,i==data[pos]&&limit);
    }
    if(!limit)
        dp[pos][h][k][sta] = ans;
    return ans;
}

ll solve(ll n)
{
    int pos = 0;
    while(n)
    {
        data[++pos] = n % 10;
        n /= 10;
    }
    return dfs(pos, 0, 0,0, true);
}

int main()
{
    ll a;
    memset(dp, -1, sizeof(dp));
    while(~scanf("%lld", &a))
        printf("%lld\n", solve(a));
    return 0;
}

HDU - 3709   找到平衡支點, 例如4139中以3爲支點4*2 + 1*1 = 9 and 9*1 = 9,則該數爲我們要找的數。

這題多出來的一步是找平衡支點,遍歷查找即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long ll;

int data[20];
ll dp[25][25][2100];
ll maxx;
ll dfs(int pos, int o,int  sta, bool limit)
{
    if(pos == 0)
        return sta==0;
    if(sta<0)
        return 0;
    if(!limit && dp[pos][o][sta]!=-1)
        return dp[pos][o][sta];
    int up = limit ? data[pos] : 9;
    ll ans = 0;
    for(int i = 0; i <= up; i++)
        ans+=dfs(pos-1,o,sta+i*(pos-o),i==data[pos]&&limit);
    if(!limit)
        dp[pos][o][sta] = ans;
    return ans;
}
ll solve(ll n)
{
    int pos = 0;
    ll ans=0;
    while(n)
    {
        data[++pos] = n % 10;
        n /= 10;
    }
    for(int i=1; i<=pos; i++)
        ans+=dfs(pos,i,0, 1);
    return ans+1-pos;  //0000計算了4次,減去pos-1次
}

int main()
{
    ll a,n,b;
    memset(dp, -1, sizeof(dp));
    scanf("%lld",&n);
    while(n--)
    {
        scanf("%lld %lld", &a,&b);
        printf("%lld\n",solve(b)-solve(a-1));
    }
    return 0;
}

 

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