码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 2089 不要62 数位dp

时间:2015-05-03 20:40:31      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:数位dp

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <cmath>
#include <cstring>
using namespace std;
int dp[10][3];
//dp[i][j] 表示数字的位数,j代表状态
//dp[i][0] 表示不存在不吉利的数字
//dp[i][1] 表示不存在吉利数字,且最高位是2
//dp[i][2] 表示存在不吉利数字
void init(){
	memset(dp,0,sizeof(dp));

	dp[0][0] = 1;//初始化一下0位的不吉利数字为1

	for(int i = 1;i <= 7;i++){
		dp[i][0] = dp[i-1][0]*9 - dp[i-1][1];//最高位不含有4的9个数字,而且因为当放第i位放6的时候,i-1不能放2所以要减去一下i-1位不存在不吉利数字切最高位为2 的情况
		dp[i][1] = dp[i-1][0];//最高位放了2其他位只要不是不吉利数字就可以
		dp[i][2] = dp[i-1][2] * 10 +dp[i-1][0] + dp[i-1][1];//i位的含有不吉利数字的个数是i-1位的含有不吉利数字的×10,因为只要后面含有不吉利数字前面不管是什么都可以所以前面×10,另外如果最高位放一个4然后后面的全部不是不吉利数字就行,还可以是最高位放上一个6然后,倒数第二位放上2就可以的不是不吉利就行

	}
}
int fun(int n){

	int len = 0,tem = n,ans,flag,a[10];

	while(n){
		a[++len] = n%10;
		n /= 10;
	}
	a[len+1] = ans = 0;

	flag = 0;
	//求出1-(n-1)之间的不吉利的数
	for(int i = len;i >= 1;i--){
		ans += dp[i-1][2] * a[i];//后面的i-1是不吉利数字之后前面就可以填上任意的
		if(flag){
			ans += dp[i-1][0] * a[i];
		}
		if(!flag && a[i] > 4){
			ans += dp[i-1][0];//如果a[i]>4那么就可以在i位上放上一个4
		}
		if(!flag && a[i+1] == 6 && a[i] > 2){//如果后一位是6这一位是大于2的
			ans += dp[i][1];
		}
		if(!flag && a[i] > 6){
			ans += dp[i-1][1];
			
		}
		if(a[i] == 4 || a[i+1] == 6 && a[i] == 2){
			flag = 1;
		}

	}
	return tem - ans;
}
int main()
{

	int n,m;
	init();


	while(cin >> n >> m,n||m){

		printf("%d\n",fun(m+1) - fun(n));
	}
	return 0;
}

hdu 2089 不要62 数位dp

标签:数位dp

原文地址:http://blog.csdn.net/qq_24667639/article/details/45460953

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!