【数位DP】[LOJ10163]Amount of Degrees
2024-10-07 22:37:17
发现自己以前对数位DP其实一窍不通...
这题可以做一个很简单的转换:一个数如果在$b$进制下是一个01串,且1的个数恰好有k个,那么这个数就是合法的(刚开始没判断必定是01串,只判断了1的个数竟然有60pts,数据可真的水~)
这个结论显然成立,也不需要什么证明啦qaq~
然后数位DP就好了
转化为b进制后要么插1要么插0,$dp[x][cnt]$表示当前处理到第i为,已经有cnt个1的情况下
转移方程:
$$dp[x][cnt]=\sum dp[x-1][cnt+1](当前位为1)$$
$$dp[x][cnt]=\sum dp[x-1][cnt](当前位为0)$$
记忆化搜索就好了
#include<bits/stdc++.h>
#define writeln(x) write(x),puts("")
#define writep(x) write(x),putchar(' ')
using namespace std;
inline int read(){
int ans=,f=;char chr=getchar();
while(!isdigit(chr)){if(chr=='-') f=-;chr=getchar();}
while(isdigit(chr)){ans=(ans<<)+(ans<<)+chr-;chr=getchar();}
return ans*f;
}void write(int x){
if(x<) putchar('-'),x=-x;
if(x>) write(x/);
putchar(x%+'');
}const int M = ;
int dp[M][M],a[M],tp,l,r,x,y,k,b;
int dfs(int x,int cnt,int lim){
if(cnt>k)return ;
if(x==)return cnt==k;
if(!lim&&dp[x][cnt]!=-)return dp[x][cnt];
int ans=,up=b-;
if(lim)up=a[x];
for(int i=;i<=up;i++){
if(i==)ans+=dfs(x-,cnt+,lim&&(a[x]==i));
else if(!i)ans+=dfs(x-,cnt,lim&&(a[x]==i));
}
if(!lim)dp[x][cnt]=ans;
return ans;
}
inline int Solve(int x){
int tp=;
while(x){a[++tp]=x%b;x/=b;}
return dfs(tp,,);
}
int main(){
memset(dp,-,sizeof(dp));
l=read(),r=read(),k=read(),b=read();
l=Solve(l-);r=Solve(r);
writeln(r-l);
return ;
}
最新文章
- js url.slice(star,end) url.lastIndexOf(&#39;/&#39;) + 1, -4
- chrome &#39;adobe flash player 已过期&#39;解决方法
- 转:一个Sqrt函数引发的血案
- AFNetworking 简单应用
- iOS使用WSDL2ObjC工具调用Webservice接口
- JavaScript---网络编程(8)-DHTML技术演示(1)
- SPI模式下MCU对SD卡的控制及操作命令
- php 按列值合并数据
- Python 3 re模块3个括号相关的语法
- 【STM32H7教程】第8章 STM32H7的终极调试组件Event Recorder
- Java利用POI读取Excel
- 剑指offer(39)平衡二叉树
- 理解inode 以及 软链接和硬链接概念区分
- Java知多少(36)内部类及其实例化
- Bootstrap3基础 input-group-btn 按钮与输入框 横向组合
- CSRF重放共计详解
- Kibana安装及使用
- [NOI.AC]COUNT(数学)
- 小程序 上啦下拉刷新window配置
- loadrunner添加变量检查点