hdu 2089 不要62 (數位dp)

引言:

在信息學競賽中,有一類與數位有關的區間統計問題。這類問題往往具有比較濃厚的數學味道,無法暴力求解,需要在數位上進行遞推等操作。

------《淺談數位類問題》 劉聰

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=2089

題意:給出一個數n,求0~n中不含4和62的數的個數。

思路:

數位dp,dp[len][s]表示長度爲len,狀態爲s的滿足條件的數的個數。 s表示上一位是否是6。

 實現的方法是參照了一個數位dp dfs實現的板子,板子中的細節請看代碼中的註釋。

code:

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long LL;
const int MAX_N=1010;
const int MAX_K=10;

int num[9];
int dp[9][2];

/*len:表示長度
  s:當前的狀態(對於此題就是上一位是否是6) 
  fp:表示之前的狀態是否充滿的(如果說充滿的此處的放置就是有限制的 否則就可以隨便放)
*/
int dfs(int len,int s,bool fp)
{
    if(len==0) return 1;
    if(!fp&&dp[len][s]!=-1) return dp[len][s];
    int res=0;
    int fmax=fp?num[len]:9;         //根據充滿狀態選擇限制條件
    for(int i=0;i<=fmax;i++){
        if(i==4||s&&i==2) continue; //跳過62和4的情況
        res+=dfs(len-1,i==6,fp&&i==fmax);
    }
    return fp? res:dp[len][s]=res;
}
int solve(int n)
{
    int len=0;
    while(n!=0){
        num[++len]=n%10;
        n/=10;
    }
    return dfs(len,0,1);
}
int main()
{
    int n,m;
    memset(dp,-1,sizeof(dp));
    while(scanf("%d%d",&n,&m),n|m){
        printf("%d\n",solve(m)-solve(n-1));
    }
    return 0;
}


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