HDU2089(数位dp入门)
来源:互联网 发布:win10平板安装ubuntu 编辑:程序博客网 时间:2024/06/06 09:56
#include<iostream>#include<string>#include<queue>#include<stdio.h>#include<string.h>#include<stdlib.h>#include<math.h>using namespace std;#define Max(a,b)(a>b?a:b)#define Mem(a,b) (memset(a,b,sizeof(a)))#define Abs(a)(a>0?a:-a)#define INF 1e20#define EPS 1e-8#define ll long longint dp[10][3];//dp[i][j],i代表数字的位数,j代表状况//dp[i][0],表示都是吉利数字//dp[i][1],表示都是吉利数字,且最高位为2 2xxxxxx//dp[i][2],表示所有不吉利数字 4xxxx || xx4xx || 62xxxx || xx62xxvoid Init(){int i;Mem( dp, 0 );dp[0][0] = 1;for( i= 1; i<= 6; i++ ){dp[i][0] = dp[i-1][0] * 9 -dp[i-1][1];//当前最高位加上不含4的9个数字的情况 //如当前位为1 则 1+1xx 1+2xx 1+3xx 1+5xx 1+6xx 1+7xx 1+8xx 1+9xx 1+0xx 所以在上一位上*9即可 //但是存在一种情况:当前最高位为6,那么要减去上一次最高位为2的情况 //因为这次最高位6和上次最高位2构成了不吉利的数字 //我们用dp[i-1][1] 记录了上一次最高位为2的情况的所有的数字,因此减去即可dp[i][1] = dp[i-1][0]; //用来记录当前最高位为2的情况。就是记录2+xx的数字的个数dp[i][2] = dp[i-1][2] * 10 + dp[i-1][0] + dp[i-1][1]; //已经含有的前面放什么都可以。 //dp[i-1][2]*10 表示前面所有的不吉利的数字在增加一个最高位之后,不吉利的数字也会增加10倍 //比如 如果一个最高位则就只有一个不吉利的数字,就是4,当增加一个最高位之后,就增加了10倍,40,41,42,43,44,45,46,47,48,49 //加上dp[i-1][0]的情况是 在上一次的所有的吉利的数字前面加上一个4.则上一次的吉利的数字都成了不吉利的数字 //加上dp[i-1][1]的情况是 在上一次的所有的最高位为2的吉利数字前加上一个6,则上一次的吉利数字都成了不吉利的数字}//如此循环6遍之后,最高位就有了6位,即从1~1000000//dp[i][1]只是用来记录最高位为2的数字。//dp[i][0]+dp[i][2] 的和 等于 所有的数字。即dp[i][0]代表所有吉利的数字,dp[i][2]代表所有不吉利的数字。因为上面一句已经讲到dp[i][1]只是用来记录最高位为2的数字。}int solve(int n){int k; int i, len = 0, tem = n, ans, flag, a[10]; while( n )//将每一位拆分放入数组 { a[ ++len ] = n % 10; n /= 10; } a[ len+1 ] = ans = 0;//ans代表不吉利的数字的个数 flag = 0; for( i = len; i >= 1; i-- ) { ans += dp[ i-1 ][ 2 ] * a[ i ];//上一次所有不吉利的数字*这次最高位的数字,表示前面所有的不吉利的数字在增加一个最高位之后,不吉利的数字也会增加这次最高位的数字大小倍 if( flag )//如果已经是不吉利了,则该位之后的数字都不是吉利数字,所以要加上这些吉利的数字(之后都变成了不吉利的)。因为在函数Init中讲到 dp[i][0]+dp[i][2] 的和 等于 所有的数字。而ans代表的是不吉利的数字的个数。 ans += dp[ i-1 ][ 0 ] * a[ i ]; if( ! flag && a[ i ] > 4)//如果此时最高位大于4,则存在有4+xxxxx的情况,则要加上4+xx的情况的数字的个数 ans += dp[ i - 1 ][ 0 ]; if( ! flag && a[ i + 1 ] == 6 && a[ i ] > 2 )//如果此时最高位大于2,且下一个最高位为6,则存在62+xxx的情况,则要加上62+xx的情况的数字的个数 ans += dp[ i ][ 1 ]; if( ! flag && a[ i ] > 6)//如果此时最高位大于6,则存在6+xx的情况,考虑到上一个最高位可能为2,所有存在62+xx的情况,则要加上62+xx的情况的数字的个数 ans += dp[ i - 1 ][ 1 ]; if( a[ i ] == 4 || ( a[ i + 1 ] == 6 && a[ i ] == 2 ) )//标记为不吉利 flag = 1; } return tem - ans;}int main(){ int l, r; Init(); while( ~scanf( "%d%d", &l , &r ) , l + r ) { printf( "%d\n", solve( r + 1 ) - solve( l ) ); //因为solve函数中并没有考虑n是不是不幸数的情况,所以r+1只算了1~r,而l只算了1~l-1,这两者相减才是正确答案 } return 0;}
0 0
- HDU2089(数位dp入门)
- HDU2089 数位dp入门
- hdu2089(数位dp入门题)
- hdu2089 不要62(数位dp入门)
- HDU2089 不要62 (数位DP入门)
- hdu2089:不要62(数位dp入门)
- hdu2089(数位dp)
- 数位dp(hdu2089)
- hdu2089(数位dp)
- HDU2089(数位DP)
- HDU2089 数位DP入门题
- 数位DP (基础) HDU2089
- HDU2089——不要62(数位dp入门)
- 数位dp入门 hdu2089 不要62
- HDU2089 不要62(数位dp入门)
- hdu2089 不要62--数位dp入门题
- HDU2089不要62(数位DP入门)
- 【数位DP】模板+入门题HDU2089 FZU2109
- 写在一切之前
- hadoop中显示每个目录大小(按照GN.MB.KB格式显示)
- Android NDK初探:应用卸载反馈实现
- Hive取随机数 rand()函数
- SQL Server 2008更改表“不允许保存更改”
- HDU2089(数位dp入门)
- (4.1.2)基础总结篇之一:Activity生命周期
- 高并发量网站解决方案
- Java API接口调用,返回json格式处理
- 设计模式 装饰者模式 带你重回传奇世界
- JavaScript学习第一天
- Linux vmstat命令实战详解
- java技术的学习提高,从“就这样用”到“为什么这样用”(一)
- c/c++参数解析