HDU 3555 Bomb(数位DP)

来源:互联网 发布:淘宝的优化建议 编辑:程序博客网 时间:2024/06/13 12:50

http://acm.hdu.edu.cn/showproblem.php?pid=3555
过年了…好懒…坎坷的回家….拜年…走亲戚…balabala…..玩了几天…然后..为了不影响进度….把插头DP跳过去了…(好懒….
第一道数位DP
感觉这个数位DP就是找到每一个数位的状态的个数,然后通过遍历这个数来找到题目需要的状态的答案
题意:给一个n,输出1~n里含有 49子序列的数的数量
思路: 最基础的数位DP,先找到每一位三种状态的数量,然后通过枚举N来找到答案

#include<map>#include<set>#include<queue>#include<stack>#include<math.h>#include<string>#include<vector>#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm> using namespace std;typedef long long LL;#define maxn 1005#define f(x) (x*1.0)#define inf 0x3f3f3f3f#define maxm maxn*maxn#define min(a,b) (a>b?b:a)#define max(a,b) (a>b?a:b)#define lowbit(x) (x&(-x))#define cheak(i) printf("%d ",i)#define lson(x) (splay[x].son[0])#define rson(x) (splay[x].son[1])#define rfor(i,a,b) for(i=a;i<=b;++i)#define lfor(i,a,b) for(i=a;i>=b;--i)#define mem(a,b) memset(a,b,sizeof(a))#define mec(a,b) memcpy(a,b,sizeof(b))LL dp[25][3];//0 不含有49的个数 //1 不含有49但最高位是9的个数 //2 含有49的个数 void init(){//寻找每一个状态在每一位的个数    dp[0][0]=1;    dp[0][1]=dp[0][2]=0;    int i;    rfor(i,1,25)     {        dp[i][0]=dp[i-1][0]*10-dp[i-1][1];        dp[i][1]=dp[i-1][0];        dp[i][2]=dp[i-1][2]*10+dp[i-1][1];    }}LL A[25];LL solve(LL n){    int len=0,i;    LL ans=0;    while(n)    {        A[++len]=n%10;        n/=10;    }    A[len+1]=0;//这一步是防止上次输入对这次造成影响    bool flag=false;     lfor(i,len,1)//从高位到地位遍历     {        ans+=dp[i-1][2]*A[i];        if(flag) ans+=dp[i-1][0]*A[i];        else if(A[i]>4) ans+=dp[i-1][1];        if(A[i+1]==4&&A[i]==9) flag=true;    }    if(flag) ans++;    return ans;}int main(){    int T;    LL n;    init();    scanf("%d",&T);    while(T--)    {        scanf("%lld",&n);        printf("%lld\n",solve(n));    }    return 0;}
0 0
原创粉丝点击