HDU 2089 数位dp入门
Posted lhclqslove
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2089 数位dp入门相关的知识,希望对你有一定的参考价值。
题目链接:(不要62)[http://acm.hdu.edu.cn/showproblem.php?pid=2089]
题解:f[i][j]表示长度为i最高位为j符合题意的个数。
根据题意可以推出状态方程;
f[i][j]=
if (j==4) f[i][j]=0
else if (j!=6) f[i][j]=Σf[i-1][k] (k=0,1,2,3,4,5,6,7,8,9)
else if (j==6) f[i][j]=Σf[i-1][k] (k=0,1,3,4,5,6,7,8,9)
然后用一个slove(int x)函数求出0到x的合法个数。具体过程看code
#include<bits/stdc++.h>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define PI 3.14159265
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define eps 1e-7
const int mod=100;
const int maxn=1e5+5;
using namespace std;
ll f[10][10];//f[i][j]
int a[10];
const int inf=0x3f3f3f3f3f3f3f;
int n,m;
void get_f()
{
//for(int i=0;i<10)f[0][i]=1;
f[0][0]=1;
for(int i=1;i<10;i++)
{
for(int j=0;j<10;j++)
{
if(j==4)f[i][j]=0;
else if(j==6)
{
for(int k=0;k<10;k++)
{
if(k==2)continue;
f[i][j]+=f[i-1][k];
}
}
else
{
for(int k=0;k<10;k++)
{
f[i][j]+=f[i-1][k];
}
}
}
}
}
ll slove(int x)
{
int pos=1;
while(x)
{
a[pos++]=x%10;
x/=10;
}
a[pos]=0;
ll ans=0;
for(int i=pos-1;i>=1;i--)
{
for(int j=0;j<a[i];j++)
{
if(j!=4&&!(a[i+1]==6&&j==2))
ans+=f[i][j];
}
if(a[i]==4)break;
if(a[i]==2&&a[i+1]==6)break;
}
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
get_f();
while(cin>>n>>m)
{
if(n==0&&m==0)
{
break;
}
cout<<slove(m+1)-slove(n)<<endl;
}
return 0;
}
以上是关于HDU 2089 数位dp入门的主要内容,如果未能解决你的问题,请参考以下文章