2018.10.15【BZOJ1833】【洛谷P2602】【ZJOI2010】数字计数(数位DP)

本文深入探讨数位DP的非递归写法,通过结构体重载运算符优化算法,详细解析状态转移方程,分享从最高位开始的统计策略,并提供完整代码实现。

BZOJ传送门

洛谷传送门


解析:

感觉不是一个很好做的数位DP。

思路:

我其实是看了hzwerhzwerhzwer的题解才会这道题的非递归写法,结构体重载运算符大法好啊orzorzorz

定义数组f[i][j][k]f[i][j][k]f[i][j][k]表示位数为iii,最高位为jjj,有数字kkk的个数。

其中最后一维kkk可以封装一个结构体,因为我们接下来要对它做很多次的整体加法。

我们先预处理出所有的fff数组,考虑DPDPDP处理。

显然有如下状态转移方程f[i][k]+=f[i][j]f[i][k]+=f[i][j]f[i][k]+=f[i][j]
这是整体加法,以及f[i][k][k]+=10if[i][k][k]+=10^if[i][k][k]+=10i

两步都很显然,第一步是统计除开最高位的低位,第二步就是统计最高位的贡献。

之后就是数位DPDPDP老套路了,分开统计1−(l−1)1-(l-1)1(l1)1−r1-r1r的答案,直接减法就是最终的答案。

怎么统计?

我们考虑从最高位开始,比如一个数可以分解成a∗10k+ba*10^{k}+ba10k+b,其中aaa是一个在[1,9][1,9][1,9]的整数,b是一个不大于10k10^k10k的数,那么仅考虑这里的贡献,答案中包含的贡献就有f[k][a]f[k][a]f[k][a]以及在aaa的出现次数中还有一个b+1b+1b+1次的贡献。

然后按照上面的思路递归处理。
当然,这个递归很轻易就写成了非递归。


代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const

inline ll getint(){
	re ll num;
	re char c;
	while(!isdigit(c=gc()));num=c^48;
	while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
	return num;
} 

struct data{
	ll a[10];
	data(){memset(a,0,sizeof a);}
	ll &operator[](cs int &offset){return a[offset];}
	friend data operator+(cs data &a,cs data &b){
		data res;
		for(int re i=0;i<10;++i)res[i]=a.a[i]+b.a[i];
		return res;
	}
}f[25][10];

ll l,r,t[20];

data solve(ll x){
	data ans;
	if(x==0)return ans[0]=1,ans;
	int len=13;
	while(t[len]>x)--len;
	for(int re i=1;i<len;++i)
	for(int re j=1;j<10;++j)
	ans=ans+f[i][j];
	++ans[0];
	ll now=x/t[len];
	for(int re i=1;i<now;++i)ans=ans+f[len][i];
	x%=t[len];
	ans[now]+=x+1;
	for(int i=len-1;i;--i){
		now=x/t[i];
		for(int re j=0;j<now;++j)
		ans=ans+f[i][j];
		x%=t[i];
		ans[now]+=x+1;
	}
	return ans;
}

signed main(){
	t[1]=1;
	for(int re i=2;i<=13;++i)t[i]=t[i-1]*10;
	for(int re i=0;i<10;++i)f[1][i][i]=1;
	for(int re i=2;i<=12;++i)
	for(int re k=0;k<10;++k)
	for(int re j=0;j<10;++j){
		f[i][k]=f[i][k]+f[i-1][j];
		f[i][k][k]+=t[i-1];
	}
	l=getint();
	r=getint();
	data res1=solve(l-1);
	data res2=solve(r);
	for(int re i=0;i<10;++i)cout<<res2[i]-res1[i]<<" ";
	return 0;
}

转载于:https://www.cnblogs.com/zxyoi/p/10047222.html

源码链接: https://pan.quark.cn/s/a4b39357ea24 在网页构建领域中,CSS3(层叠样式表第三版)为程序员们提供了多样化的视觉表现手法和用户交互功能。在此案例中,我们聚焦于一种普遍的用户交互设计——"CSS3鼠标指针停留在图片上时的放大效果",即当用户将鼠标光标移动至图片上时,图片会自动进行放大,从而增强了用户的参与度和视觉冲击力。此类效果经常应用于商品展示或图像预览环节,有助于提升网站的整体用户体验。 我们需要掌握HTML5中的`<img>`标签,它是用于嵌入图像的基本组件。在`<img>`标签内部,我们可以通过`src`属性来设定图像的地址,`alt`属性用于在图像无法加载时提供替代说明文字,此外还包括`width`和`height`属性用于设定图像的尺寸。 ```html <img src="image.jpg" alt="图片的说明文字" width="200" height="200"> ``` 构建图片在鼠标悬停时放大这一功能的关键在于CSS3的`:hover`伪类选择器。`:hover`用于选取鼠标光标悬停其上的元素,结合transform属性,我们可以便捷地实现图片的放大操作。以下是一个基础的示例: ```css img { transition: transform 0.3s ease; /* 引入过渡效果 */ } img:hover { transform: scale(1.2); /* 鼠标悬停时,图片放大到原尺寸的120% */ } ``` 在这段代码里,`transition`属性设置了图像在变化过程中的过渡效果,`0.3s`代表过渡持续的时间,`ease`是预设的缓动效果,使得变化过程更加流畅。`...
内容概要:本文系统研究了基于最优滑模控制的永磁同步电机(PMSM)调速系统模型,并通过Simulink平台实现了完整的仿真实验。研究聚焦于滑模控制在电机调速中的应用,重点对比了经典滑模、改进滑模与最优滑模三种控制策略的性能差异,深入分析了最优滑模控制在提升系统动态响应速度、增强抗干扰能力及改善稳态精度方面的优势。文章详细阐述了电机数学建模、控制器设计、稳定性分析与仿真验证全过程,突出了最优滑模控制在有效抑制抖振现象、提高系统鲁棒性方面的关键技术特点。; 适合人群:具备自动控制原理、电机控制理论基础及Simulink仿真技能的电气工程、自动化、控制科学与工程等相关领域的研究生、科研人员以及从事高性能电机驱动系统开发的工程技术人员。; 使用场景及目标:①为高等院校和科研机构开展先进电机控制算法的教学与科研工作提供理论依据和仿真案例;②为工业界高性能伺服系统、新能源汽车电驱动系统等领域的控制器设计提供技术参考与验证手段;③帮助研究人员深入掌握滑模控制的设计方法、参数整定技巧及其在实际工程系统中的实现路径。; 阅读建议:建议读者结合提供的Simulink模型进行同步操作与仿真,重点关注不同滑模控制器的结构设计与参数设置,通过对比仿真结果直观理解最优滑模控制的优越性。同时,可在此基础上探索将最优滑模控制与自抗扰、预测控制等先进控制理论相结合,进一步拓展其在复杂非线性系统中的应用研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值