3 1 50 500
0 1 15HintFrom 1 to 500, the numbers that include the sub-sequence "49" are "49","149","249","349","449","490","491","492","493","494","495","496","497","498","499", so the answer is 15.
貌似数位dp暂时发现了两种题型,本质还是一种没错==之前的n进制是需要把原数字转化成n叉数,截取自己需要的部分。
这次说的题是针对这个数字本身来说的,也可以认为是一个十进制,就是一个10叉树,我怎么这么机智==用递推解释就是把一个树杈接到当前节点后面形成新的树杈。以这个题为例,dp[i][0] dp[i][1] dp[i][2]分别表示i长度下:不存在不吉利数字;不存在不吉利数字开头是9;存在不吉利数字。首先预处理三个数组,然后就简单啦
主要还是不要62那个题没学明白,用的不是标准的数位dp导致的
/************* hdu3555 2016.3.11 15MS 1736K 1525 B C++ **************/ #include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> using namespace std; long long dp[22][3]; /* * dp[i][0],表示长度为i,不存在不吉利数字 * dp[i][1],表示长度为i,不存在不吉利数字,且最高位为2 * dp[i][2],表示长度为i,存在不吉利数字 */ void init() { dp[0][0]=1;dp[0][1]=0;dp[0][2]=0; for(int i=1;i<=20;i++) { dp[i][0]=dp[i-1][0]*10-dp[i-1][1];//在最高位加上除4以外的9个数字,但要减掉2之前加上6 dp[i][1]=dp[i-1][0];//在不含不吉利数字的最高位加上2 dp[i][2]=dp[i-1][2]*10+dp[i-1][1]; //在已有不吉利数字前加任意数字,或者无不吉利数字的最高位加4,或者在2前面加6 } } int bit[22]; long long solve(long long n) { int len=0; long long tmp=n; while(n) { bit[++len]=n%10; n/=10; } bit[len+1]=0; long long ans=0; bool flag=false; for(int i=len;i>=1;i--) { ans+=dp[i-1][2]*bit[i]; if(flag)//高位已经出现49,后面随意 ans+=dp[i-1][0]*bit[i]; if(!flag&&bit[i]>4) ans+=dp[i-1][1]; if(bit[i+1]==4&&bit[i]==9) flag=true; } if(flag)ans++;//这个数本身 return ans; } int main() { //freopen("cin.txt","r",stdin); //freopen("out.txt","w",stdout); init(); long long n; int t; scanf("%d",&t); while(t--) { scanf("%I64d",&n); printf("%I64d\n",solve(n)); } return 0; }