HDU-2089不要62-暴力或數位DP入門
阿新 • • 發佈:2018-02-25
之前 scanf href esp ostream += log main string
不要62
題意:給定區間,求在這個區間中有多少個數字,不包含4且不包含62;
這道題作為數位DP的入門題;
暴力也是可以過
#include<cstdio> #include <iostream> #include <cstring> #include <string> #include <algorithm> using namespace std; const int maxn =1e6+7; int a[maxn]; bool check(int x) { while(x>0) { if(x%10==4)return true; if(x%100==62)return true; x/=10; } return false; } int main(){ int sum = 0; for(int i=1;i<=1000000;i++) { if(check(i)){a[i]=sum;continue;} sum++; a[i]=sum; } int l,r; while(~scanf("%d%d",&l,&r)&&l+r) { printf("%d\n",a[r]-a[l-1]); } return 0; }
當然數位DP更快,利用記憶化DFS
#include <iostream> #include <cstring> #include <string> #include <algorithm> #include <cstdio> using namespace std; int dp[10][3],digit[10]; int dfs(int pos,bool pre_6,bool limit) { if(pos==0)return 1; if(!limit&&dp[pos][pre_6]>=0)return dp[pos][pre_6]; int ans=0,num=limit?digit[pos]:9; for(int i=0;i<=num;i++) { if(i==4||(pre_6&&i==2)) continue; ans += dfs(pos-1,i==6,limit&&i==num); //只有之前有限制現在的達到了上限才能構成限制 } return limit?ans:dp[pos][pre_6] = ans;//如果有限制,那麽就不能記憶化,否則記憶的是個錯誤的數. } int solve(int x) { int len = 0; while(x>0) { digit[++len]=x%10; //將數字存在digit數組中 x/=10; } return dfs(len,false,true); } int main(){ memset(dp,-1,sizeof(dp)); int l,r; while(scanf("%d%d",&l,&r),l+r) { printf("%d\n",solve(r)-solve(l-1)); } return 0; }
HDU-2089不要62-暴力或數位DP入門