1. 程式人生 > >【HDU】6148 Valley Numer

【HDU】6148 Valley Numer

技術 很難 const ++ 速度 aps size 技術分享 ring

【算法】數位DP

【題意】定義V-number為從左到看單位數字未出現先遞增後遞減現象的數字,求0~N中滿足條件的數字個數。T<=200,lenth(n)<=100

【題解】百度之星2017復賽,作為送分題出現,拿來練數位DP模板了。

位數多,讀入記得用字符串。

記憶化要將有關變量全部納入。

需要取模的時候別習慣性寫"+=",特別是競速賽,改起來很難受。

-1的變量前加~就和0一樣了。

最後自己造數據測試了一下,記憶化搜索的速度簡直全面碾壓遞推啊!(從此堅定了信仰)

技術分享
#include<cstdio>
#include<algorithm>
#include<cstring>
#include
<cctype> #define ll long long using namespace std; const ll maxn=110,MOD=1000000007; ll f[maxn][2][10],a[maxn],n; ll dfs(ll pos,ll state,ll limit,ll pre){ if(pos==-1){if(~pre)return 1;else return 0;} if(!limit&&~pre&&~f[pos][state][pre])return f[pos][state][pre]; ll up=limit?a[pos]:9
; ll ans=0; for(int i=0;i<=up;i++){ if(pre==-1&&i==0)ans=(ans+dfs(pos-1,state,limit&&i==up,pre))%MOD;else if(pre==-1&&i!=0)ans=(ans+dfs(pos-1,state,limit&&i==up,i))%MOD;else if(state==0)ans=(ans+dfs(pos-1,i>pre,limit&&i==up,i))%MOD;else
if(state==1&&i>=pre)ans=(ans+dfs(pos-1,state,limit&&i==up,i))%MOD;//取模!!! } if(!limit&&~pre)f[pos][state][pre]=ans;//記憶化:當前狀態和pos,state,pre三者都有關系!!! return ans; } char s[maxn]; int main(){ ll T; scanf("%lld",&T); memset(f,-1,sizeof(f)); while(T--){ scanf("%s",s+1); n=strlen(s+1); for(int i=1;i<=n;i++)a[n-i]=s[i]-0; printf("%lld\n",dfs(n-1,0,1,-1)); } return 0; }
View Code

【HDU】6148 Valley Numer