您的位置:首页 > 其它

HDU 2089 不要62 [数位dp]

2016-08-12 10:37 337 查看

题干

走你

题解

/**
*数位dp,转移方程很好想,需要仔细考虑的是,怎样通过计算出来的dp数组
*得出结果,也就是本题目里面的work()函数,我写的有点乱,但是好在AC了
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[10][10];
int work(int n){
int digit[10],cnt = 0;
while(n){
digit[cnt++] = n % 10;
n /= 10;
}
reverse(digit,digit + cnt);
int ans = 0;
digit[cnt + 1] = 0;
for(int k=0; k<cnt; k++){
if(k>=0 && digit[k-1] == 4){
break;
}
if(k-2>=0 && digit[k-2]==6 && digit[k-1] == 2){
break;
}
for(int i=0;i<digit[k];i++){
if(k-1>=0 && digit[k-1] == 6 && i == 2){
continue;
}
ans += dp[cnt - k][i];
}
}
return ans;
}
int num(int m){
int a[10],cnt = 0,i;
while(m){
a[cnt++] = m % 10;
m /= 10;
}
for(i=0;i<cnt;i++){
if(a[i] == 4){
return 0;
}
if(i+1<cnt && a[i] == 2 && a[i+1] == 6){
return 0;
}
}
return 1;
}
void init(){
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(int i=1;i<=7;i++){
for(int j=0;j<10;j++){
if(j != 4){
for(int k=0;k<10;k++){
if(k != 4 && !(j==6&&k==2)){
dp[i][j] += dp[i-1][k];
}
}
}
}
}
}
int main(){
int n,m;
init();
while(~scanf("%d%d",&n,&m)){
if(n==0&&m==0)break;
if(n < m){
printf("%d\n",work(m)  -  work(n) + num(m));
}else{
printf("%d\n",num(m));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dp