动态规划六
复健
动态规划(六)数位
数位的特点:求某个区间内,满足某种性质的数的个数
技巧一:类似前缀和的思想,转化为求解
技巧二:从高位到低类填数,分类讨论;
比如比小的数的个数,对于数,如果某一位填了,则后面每一位都可填的任意数,如果填,则继续讨论下一位(这样才不会大于)
数字游戏
表示一共有位,且最高位数字为的不降数个数
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 12
using namespace std;
int a[maxn],f[maxn][maxn];
void init()
{
for(int i=0;i<=9;i++) f[1][i]=1;
for(int i=2;i<=maxn;i++)
{
for(int j=0;j<=9;j++)
{
for(int k=j;k<=9;k++) f[i][j]+=f[i-1][k];
}
}
}
int dp(int n)
{
if(!n) return 1;//特判,0也是一个不降数
int cnt=0;
while(n) a[++cnt]=n%10,n/=10;
int res=0,last=0;
for(int i=cnt;i>=1;--i)
{
int now=a[i];
for(int j=last;j<now;j++) res+=f[i][j];
if(now<last) break;
last=now;
if(i==1) res++;//就是0也是一个不降数
}
return res;
}
int main()
{
init();
int l,r;
while(cin>>l>>r)
{
cout<<dp(r)-dp(l-1)<<endl;
}
return 0;
}
数
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define maxn 10
using namespace std;
int f[maxn][maxn];
void init()
{
for(int i=0;i<=9;i++) f[1][i]=1;
for(int i=2;i<=10;i++)
{
for(int j=0;j<=9;j++)
{
for(int k=0;k<=9;k++)
{
if(abs(k-j)>=2) f[i][j]+=f[i-1][k];
}
}
}
}
int dp(int n)
{
if(!n) return 0;
vector<int> a;
while(n) a.push_back(n%10),n/=10;
int last=-2;
int res=0;
for(int i=a.size()-1;i>=0;i--)
{
for(int j=(i==a.size()-1);j<a[i];j++)
{
if(abs(j-last)>=2) res+=f[i+1][j];
}
if(abs(a[i]-last)<2) break;
last=a[i];
if(!i) res++;
}
for(int i=a.size()-1;i>=1;i--)
{
for(int j=1;j<=9;j++) res+=f[i][j];
}
return res;
}
int main()
{
int a,b;
cin>>a>>b;
init();
printf("%d\n",dp(max(a,b))-dp(min(a,b)-1));
return 0;
}
度的数量
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 12
using namespace std;
int a[maxn],f[maxn][maxn];
int k,B;
void init()//预处理组合数
{
for(int i=0;i<=maxn;i++) f[i][0]=1;
for(int i=1;i<=maxn;i++)
{
for(int j=1;j<=i;j++)
{
f[i][j]=f[i-1][j-1]+f[i-1][j];
}
}
}
int dp(int n)
{
if(!n) return 0;//特判,0也是一个不降数
int cnt=0;
while(n) a[++cnt]=n%B,n/=B;
int res=0,last=0;
for(int i=cnt;i>=1;--i)
{
int now=a[i];
if(now)
{
res+=f[i-1][k-last];
if(now>1)
{
if(k-last-1>=0) res+=f[i-1][k-last-1];
break;
}
else
{
last++;
if(last>k) break;
}
}
if(i==1&&last==k) res++;
}
return res;
}
int main()
{
init();
int l,r;
cin>>l>>r>>k>>B;
cout<<dp(r)-dp(l-1)<<endl;
return 0;
}
正因无所有,才会无所畏
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!