HDU3709 Balanced Number[數位DP]

題意:
給T組數據,每組數據給出一個x和y,求出[x,y]當中滿足以其中一位爲平衡點,滿足在平衡點的左右兩邊的力矩大小一致。

題解:
這道題要注意前導零的問題,因爲不記錄前導零,如果左界也不是0,會多出len-1種情況(len是這個數共有多少位),那麼如果左界是0,就需要記錄一下。
因爲有這種問題,所以我寫的時候記錄了前導零,然後如果出現邊界有0的情況,左界出現的話,爲了補上,而把ans預置爲-1(因爲計算過程是solve(y)-solve(x-1)所以當前數爲-1的時候,代表邊界爲0,最小也只有爲0,補上-1即在最終結果上面+1)。然後,要枚舉出每一位作爲平衡點的時候的情況,然後將所有情況的結果加起來,就是我們需要的結果了。

所以結果的本身是求符合這個式子,同時,因爲力矩在計算過程中不可能存在負數,所以如果出現了負數,那麼就直接可以返回0了,因爲是不可能的情況。

狀態轉移的話,dp[i][j][k] 首先第一維記錄當前位置,第二維記錄平衡點是哪個位置,第三維記錄所有sum的結果,而sum的最大值大概取9*9*18(即取最邊上的界最大值的sum)。


#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
using namespace std;
typedef long long ll;
const int N=20;
const int M=1500;//9*9*18
ll dp[N][N][M];
int num[N];
ll dfs(int pos,int sum,int mid,bool first,bool limit)
{
    if (pos==-1)
        return first?(!sum):0;
    if (sum<0)
        return 0;
    if (!limit && first && dp[pos][mid][sum]!=-1)
        return dp[pos][mid][sum];
    int up=limit?num[pos]:9;
    ll cnt=0;
    for (int i=0 ; i<=up ; ++i)
    {
        if (!first)
        {
            if (i)
                cnt+=dfs(pos-1,sum+(pos-mid)*i,mid,1,limit && i==num[pos]);
            else
                cnt+=dfs(pos-1,sum+(pos-mid)*i,mid,first,limit && i==num[pos]);
        }
        else
            cnt+=dfs(pos-1,sum+(pos-mid)*i,mid,first,limit && i==num[pos]);
    }

    if (!limit && first)
        dp[pos][mid][sum]=cnt;
    return cnt;
}
ll solve(ll n)
{
    int pos=0;
    ll ans=n==-1?-1:0;//如果左界爲0 補上一個平衡(因爲dfs過程中不計算前導0,即漏算了0的情況)
    if (n==-1)
        n=0;
    while (n)
    {
        num[pos++]=n%10;
        n/=10;
    }
    for (int i=pos-1 ; i>=0 ; --i)
        ans+=dfs(pos-1,0,i,0,1);
    return ans;
}
int main()
{
    memset(dp,-1,sizeof(dp));
	int T;
	scanf("%d",&T);
	while (T--)
    {
        ll x,y;
        scanf("%lld%lld",&x,&y);
        printf("%lld\n",solve(y)-solve(x-1));
    }
	return 0;
}




發佈了51 篇原創文章 · 獲贊 15 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章