DP - 數位DP - SCOI 2009 - Windy數 + HDU 2089 - 不要62
1、SCOI 2009 - Windy數
Windy 定義了一種 Windy 數:不含前導零且相鄰兩個數字之差至少爲 2 的正整數被稱爲 Windy 數。
Windy 想知道,在 A 和 B 之間,包括 A 和 B,總共有多少個 Windy 數?
輸入格式
共一行,包含兩個整數 A 和 B。
輸出格式
輸出一個整數,表示答案。
數據範圍
1≤A≤B≤2×109
輸入樣例1:
1 10
輸出樣例1:
9
輸入樣例2:
25 50
輸出樣例2:
20
——《數字遊戲》
注意:
代碼:
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=11;
int f[N][N];
void cal()
{
for(int i=0;i<=9;i++) f[1][i]=1;
for(int i=2;i<N;i++)
for(int j=0;j<=9;j++)
for(int k=0;k<=9;k++)
if(abs(j-k)>=2)
f[i][j]+=f[i-1][k];
}
int dp(int n)
{
if(!n) return 0;
vector<int> V;
while(n) V.push_back(n%10),n/=10;
int res=0,last=-2;
for(int i=V.size()-1;i>=0;i--)
{
int x=V[i];
for(int j=(i==V.size()-1);j<x;j++)
if(abs(j-last)>=2)
res+=f[i+1][j];
if(abs(x-last)>=2) last=x;
else break;
if(!i) res++;
}
for(int i=1;i<V.size();i++)
for(int j=1;j<=9;j++)
res+=f[i][j];
return res;
}
int main()
{
cal();
int l,r;
cin>>l>>r;
cout<<dp(r)-dp(l-1)<<endl;
return 0;
}
2、HDU 2089 - 不要62
杭州人稱那些傻乎乎粘嗒嗒的人爲 62(音:laoer)。
杭州交通管理局經常會擴充一些的士車牌照,新近出來一個好消息,以後上牌照,不再含有不吉利的數字了,這樣一來,就可以消除個別的士司機和乘客的心理障礙,更安全地服務大衆。
不吉利的數字爲所有含有 4 或 62 的號碼。例如:62315,73418,88914 都屬於不吉利號碼。但是,61152 雖然含有 6 和 2,但不是 連號,所以不屬於不吉利數字之列。
你的任務是,對於每次給出的一個牌照號區間 [n,m],推斷出交管局今後又要實際上給多少輛新的士車上牌照了。
輸入格式
輸入包含多組測試數據,每組數據佔一行。
每組數據包含一個整數對 n 和 m。
當輸入一行爲“0 0”時,表示輸入結束。
輸出格式
對於每個整數對,輸出一個不含有不吉利數字的統計個數,該數值佔一行位置。
數據範圍
1≤n≤m≤109
輸入樣例:
1 100
0 0
輸出樣例:
80
分析:
代碼:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N=11;
int f[N][N];
void cal()
{
for(int i=0;i<=9;i++)
if(i!=4)
f[1][i]=1;
for(int i=2;i<N;i++)
for(int j=0;j<=9;j++)
{
if(j==4) continue;
for(int k=0;k<=9;k++)
{
if(k==4 || j==6&&k==2) continue;
f[i][j]+=f[i-1][k];
}
}
}
int dp(int n)
{
if(!n) return 1;
vector<int> V;
while(n) V.push_back(n%10),n/=10;
int res=0,last=0;
for(int i=V.size()-1;i>=0;i--)
{
int x=V[i];
for(int j=0;j<x;j++)
{
if(j==4 || last==6&&j==2) continue;
res+=f[i+1][j];
}
if(x==4 || last==6&&x==2) break;
last=x;
if(!i) res++;
}
return res;
}
int main()
{
cal();
int l,r;
while(cin>>l>>r,l||r)
cout<<dp(r)-dp(l-1)<<endl;
return 0;
}