博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[HDU]3555Bomb
阅读量:6838 次
发布时间:2019-06-26

本文共 2073 字,大约阅读时间需要 6 分钟。

http://acm.hdu.edu.cn/showproblem.php?pid=3555

第一次做位数DP,卧槽,看了别人一晚上的代码,又调了一早上才做出来,艹艹艹!

这道题讲的是,给定任意n,计算从1~n中有多少数包含连续的49.

--------------------------------------分割线-----------------------------------------------------------

这些是状态转移方程

dp[i][0]=dp[i-1][0]*10-dp[i-1][1];                         //代表不含49 (当位数增加一位,不含49的数增加10倍,但是要减去一个以9开头的)

dp[i][1]=dp[i-1][0];                                             //代表不含49,但以9开头(当位数增加一位,就增长了在原来不以9开头的那些)
dp[i][2]=dp[i-1][2]*10+dp[i-1][1];                       //代表包含49(当位数增加一位,之前已经包含49的增加10倍,另外要加上现在开头为4和之前开头为9组合成49的数)

当然状态转移方程不止这一种,如:

 

 

dp[k][0]=dp[k-1][0]*9+dp[k-1][1]*8;                   //dp[][0]表示不包含49并且以非4结尾的个数

dp[k][1]=dp[k-1][0]+dp[k-1][1];                          //dp[][1]表示不包含49并且以4结尾的个数

dp[k][2]=dp[k-1][1]+dp[k-1][2]*10;                     //dp[][2]表示包含49的个数

--------------------------------------分割线-----------------------------------------------------------

另外,此题N (1 <= N <= 2^63-1),所以要输入的话要用字符型(即字符串输入),或定义成long long

#include"stdio.h"#include"stdlib.h"#include"string.h"long long dp[20][3];int main() {     int t,len,i,j,a[20],flag,last;     long long n,sum;     memset(dp,0,sizeof(dp));                      //初始化      dp[0][0]=1;     for(i=1;i<21;i++)                            //算出彼此关系,下面计算时,直接调用      {               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];      }     scanf("%d",&t);     while(t--)     {          scanf("%I64d",&n);                         n++;                   //处理末尾2位是49的特殊情况           len=0;          memset(a,0,sizeof(a));          while(n)          {              a[++len]=n%10;              n=n/10;          }           flag=0;          sum=0;          last=0;          for(i=len;i>=1;i--)          {                              sum+=dp[i-1][2]*a[i];                if(flag)                  //如果其高位存在49,则低位不管是什么数都存在                sum+=dp[i-1][0]*a[i];               if(!flag&&a[i]>4)           //2位置,且首位大于等于5,至少存在低一位有9的情况的个数                sum+=dp[i-1][1];               if(last==4&&a[i]==9)               flag=1;                last=a[i];                }          printf("%I64d\n",sum);     }    // system("pause");}

 

转载于:https://www.cnblogs.com/sjy123/p/3247731.html

你可能感兴趣的文章
scau实验题 8596 Longest Ordered Subsequence
查看>>
getopt例子
查看>>
浅说Java中的反射机制(一)
查看>>
jquery之行自加自减
查看>>
单向链表的有关操作(链式存储结构)
查看>>
Spring @PostConstruct and @PreDestroy example
查看>>
软件架构师2
查看>>
单链表的操作
查看>>
没事抽空学——常用界面组件属性
查看>>
《程序员代码面试指南》第二章 链表问题 构造链表和节点的实体
查看>>
【LeanEAP.NET】精益企业应用平台---源码&Demo下载
查看>>
Django restfulframework 开发相关知识 整理
查看>>
去掉数组中重复的数字。
查看>>
Poj 2887-Big String Splay
查看>>
docker笔记-docker-container
查看>>
SuperSocket 服务管理器 (ServerManager)
查看>>
Eclipse launch failed.Binary not found解决方案
查看>>
NSGA-II入门C1
查看>>
结对第2次作业——WordCount进阶需求
查看>>
两个经典递归问题:菲波那契数列 + 汉诺塔
查看>>