数位DP模板+裸体
Posted zjj0624
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数位DP模板+裸体相关的知识,希望对你有一定的参考价值。
题意
嘟嘟讨厌38和4,给你一个区间,让你找到区间中所有让人讨厌的数字。
记忆化的数位DP
代码
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e5+10;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int num[9];
int f[9][3];
int dfs(int pos,int state,bool flag)
{
if(pos==0) return state==2;
if(flag&&f[pos][state]!=-1) return f[pos][state];
int x=flag?9:num[pos];
int ans=0;
for(int i=0 ; i<=x ; i++)
{
if(i==4||state==2||(i==8&&state==1)) ans+=dfs(pos-1,2,flag||i<x);
else if(i==3) ans+=dfs(pos-1,1,flag||i<x);
else ans+=dfs(pos-1,0,flag||i<x);
}
if(flag) f[pos][state]=ans;
return ans;
}
int cal(int n)
{
memset(num,0,sizeof num);
int pos=0;
while(n) num[++pos]=n%10,n/=10;
return dfs(pos,0,false);
}
int main()
{
int l,r;
cin>>l>>r;
while(l!=0||r!=0)
{
memset(f,-1,sizeof(f));
cout<<cal(r)-cal(l-1)<<endl;
cin>>l>>r;
}
return 0;
}
用DP预处理的数位DP
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 10;
const int MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int f[N][10][2];
void init()
{
f[1][4][1]=1;
for(int i=0 ; i<N ; i++) f[1][i][0]=1;
f[1][4][0]=0;
for(int i=2 ; i<N ; i++)
for(int j=0 ; j<=9 ; j++)
for(int k=0 ; k<=9 ; k++)
{
f[i][j][1]+=f[i-1][k][1];
if(j==3)
{
if(k!=8) f[i][3][0]+=f[i-1][k][0];
else f[i][3][1]+=f[i-1][8][0];
}
else if(j==4)
{
f[i][4][1]+=f[i-1][k][0];
}
else f[i][j][0]+=f[i-1][k][0];
}
}
int dp(int n)
{
vector<int>nums;
while(n) nums.push_back(n%10),n/=10;
int ans=0;
int pre=0;
int state=0;
for(int i=nums.size()-1 ; i>=0 ; i--)
{
int x=nums[i];
for(int j=0 ; j<x ; j++)
{
ans+=f[i+1][j][1];
if(pre==3&&j==8&&state==0) ans+=f[i+1][j][0];
if(state) ans+=f[i+1][j][0];
}
if((pre==3&&x==8)||x==4) state=1;
pre=x;
if(!i&&state) ans++;
}
return ans;
}
int main()
{
init();
/*for(int i=1 ; i<=4 ; i++)
{
for(int j=0 ; j<=9 ; j++) cout<<f[i][j][1]<<" ";
cout<<endl;
}
for(int i=1 ; i<=4 ; i++)
{
for(int j=0 ; j<=9 ; j++) cout<<f[i][j][0]<<" ";
cout<<endl;
}*/
int l,r;
cin>>l>>r;
while(l!=0||r!=0)
{
cout<<dp(r)-dp(l-1)<<endl;
//cout<<dp(l-1)<<" "<<dp(r)<<" "<<dp(r)-dp(l-1)<<endl;
cin>>l>>r;
}
/*for(int i=1 ; i<=5 ; i++)
{
for(int j=0 ; j<=9 ; j++) cout<<f[i][j][1]<<" ";
cout<<endl;
}*/
return 0;
}
第二个用DP预处理的数位DP,让我整整调了一天,细节真的太多了。。。
以上是关于数位DP模板+裸体的主要内容,如果未能解决你的问题,请参考以下文章