1. 程式人生 > >HDU-2089不要62-暴力或數位DP入門

HDU-2089不要62-暴力或數位DP入門

之前 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入門