1. 程式人生 > >【hdu2089】不要62

【hdu2089】不要62

string sin 範圍 完全 std iostream ont 初始化 不同的

驚奇地發現今天居然和dalao的題單重了不少23333333333333

這是我第一次做數位dp,感覺這個題目還是比較茲磁的

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int l,r,dp[20][15],a[20];
int dfs(int pos,int las,int fl,bool flag)//pos是當前位置,las是上次選的那個數,fl判斷上次選的數是否為6,flag判斷pos位上是否有枚舉限制 
{
    if(pos==0
)//答案成立,返回1 return 1; if(!flag&&dp[pos][las]!=-1)//如果flag==1的時候也返回,那麽像213的時候會使答案偏大 return dp[pos][las]; int ding=(flag)?a[pos]:9;//判斷這一位上是否有限制最大能枚舉的數 int re=0; for(int i=0;i<=ding;i++) { if(i==4||(las==6&&i==2))//不能出現4或者62 continue
; re+=dfs(pos-1,i,i==6,flag&&i==a[pos]); } if(!flag)//如果flag==1說明這一位有限制,並不完全將第pos位上一次選的las的狀態完全包含,所以不能賦值 dp[pos][las]=re; return re; } int solve(int x) { int pos=0; while(x>0)//先拆分成一位位的數字 a[++pos]=x%10,x/=10; return dfs(pos,-1,0,1);//flag初始設為0是因為數位長度+1位確實是0
} int main() { memset(dp,-1,sizeof(dp));//每次輸入的只是不同的數據範圍,但是不會影響dp數組的答案,所以只初始化一遍就好 while(~scanf("%d%d",&l,&r)) { if(l==0&&r==0) break; printf("%d\n",solve(r)-solve(l-1));//l也被包含在答案區間一部分 } }

【hdu2089】不要62