洛谷P2657 [SCOI2009]windy數 [數位DP,記憶化搜索]


  題目傳送門

windy數

題目描述

windy定義了一種windy數。不含前導零且相鄰兩個數字之差至少為2的正整數被稱為windy數。 windy想知道,

在A和B之間,包括A和B,總共有多少個windy數?

輸入輸出格式

輸入格式:

 

包含兩個整數,A B。

 

輸出格式:

 

一個整數

 

輸入輸出樣例

輸入樣例#1: 
1 10
輸出樣例#1: 
9
輸入樣例#2: 
25 50
輸出樣例#2: 
20

說明

100%的數據,滿足 1 <= A <= B <= 2000000000 。

 


  分析:

  據大佬說這是一道數位DP模板???我DP不好別騙我QWQ。。。

  好吧,一開始打了個暴搜看能水多少,可能我寫掛了只拿10分QAQ???然后打了一下正解記憶化搜索,貌似真是一個數位DP模板???看來還是我太菜了。。。

  這道題需要注意的就是當前搜索的情況如果是前導零或者頂端情況的時候需要特判,所以在搜索的時候加入兩個bool變量判斷一下,剩下的貌似真就是一個模板了。。。

  Code:

 

//It is made by HolseLee on 22rd July 2018
//Luogu.org P2657
#include<bits/stdc++.h>
using namespace std;
int num[11],dp[11][11];
inline int read()
{
  char ch=getchar();int num=0;
  while(ch<'0'||ch>'9')ch=getchar();
  while(ch>='0'&&ch<='9'){
    num=num*10+ch-'0';ch=getchar();}
  return num;
}
inline int Abs(int x)
{
  return x>0?x:-x;
}
inline int dfs(int len,int las,bool top,bool zero)
{
  if(len==0)return 1;
  if(!top&&!zero&&dp[len][las]!=-1)
    return dp[len][las];
  int cnt=0,maxx=(top?num[len]:9);
  for(int i=0;i<=maxx;i++){
    if(Abs(i-las)<2)continue;
    int p=i;if(zero&&i==0)p=-555;
    cnt+=dfs(len-1,p,top&&(i==maxx),(p==-555));
  }
  if(!zero&&!top)dp[len][las]=cnt;
  return cnt;
}
inline int work(int x)
{
  int tot=0;
  while(x){num[++tot]=x%10;x/=10;}
  memset(dp,-1,sizeof(dp));
  return dfs(tot,-555,true,true);
}
int main()
{
  int x=read();int y=read();
  printf("%d",work(y)-work(x-1));
  return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM