初学 数位dp(HDU 2089,洛谷 P2657 [SCOI2009]windy数)
例题1:HDU 2089
#include<bits/stdc++.h> using namespace std; #define maxn 300005 #define ll long long int n,m; int a[20],dp[20][2]; int dfs(int pos,int pre,int sta,bool limit){ if(pos==0)return 1; if(!limit&&dp[pos][sta]!=-1)return dp[pos][sta]; int up=limit ? a[pos] : 9; int ans=0; for(int i=0;i<=up;i++){ if((pre==6&&i==2)||i==4)continue; ans+=dfs(pos-1,i,i==6,limit&&i==a[pos]); } if(!limit)dp[pos][sta]=ans; return ans; } int slove(int x){ int pos=0; while(x){ a[++pos]=x%10; x/=10; } return dfs(pos,0,0,true); } int main() { while(~scanf("%d %d",&n,&m)&&(n+m)){ memset(dp,-1,sizeof(dp)); cout<<slove(m)-slove(n-1)<<endl; } }
#include<bits/stdc++.h> using namespace std; #define maxn 300005 #define ll long long int n,m,cnt; int a[20],dp[20][20]; int dfs(int pos,int pre,bool lead,bool limit){ if(pos==0)return 1; if(!lead&&!limit&&dp[pos][pre]!=-1)return dp[pos][pre]; int up=limit ? a[pos] : 9; int ans=0; for(int i=0;i<=up;i++){ if(!lead&&abs(i-pre)<2)continue; ans+=dfs(pos-1,i,lead&&i==0,limit&&i==a[pos]); } if(!limit&&!lead)dp[pos][pre]=ans; return ans; } int solve(int x){ int pos=0; while(x){ a[++pos]=x%10; x/=10; } return dfs(pos,0,true,true); } int main() { memset(dp,-1,sizeof(dp)); cin>>n>>m; cout<<solve(m)-solve(n-1)<<endl; return 0; }
希望用自己的努力为自己赢得荣誉。