AtCoder Beginner Contest 194 F - Digits Paradise in Hexadecimal 数位dp
传送门
文章目录
- 题意:
- 思路:
题意:
给一个161616进制的串NNN,让你求1−N1-N1−N中有多少个数有kkk个不同的数且没有前导零。
思路:
NNN很大,有2e52e52e5了,那么就比较明显是个数位dpdpdp了。首先没有前导零需要控制,还需要控制枚举是否能达到上界。根据这个题还需要存一个有多少个不同的数,我们这个可以状压一下。最后记一个位置即可。
设dp[pos][state][flag][lead]dp[pos][state][flag][lead]dp[pos][state][flag][lead]为到了pospospos位置,状态为statestatestate,是否能枚举到上界flagflagflag,以及是否存在前导零leadleadlead。让后跑裸的数位dpdpdp就好啦。
复杂度约为O(2e5∗k∗16)O(2e5*k*16)O(2e5∗k∗16),实际跑起来很快。
当然也可以将[flag][lead][flag][lead][flag][lead]两维去掉,让后返回和赋值的时候特判一下就好啦。
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=200010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n,k;
int a[N];
char s[N];
int f[N][20][2][2];int dfs(int pos,int state,int flag,int lead)
{int cnt=__builtin_popcount(state);if(cnt>k) return 0;if(pos==n+1) return cnt==k&&lead;if(f[pos][cnt][flag][lead]!=-1) return f[pos][cnt][flag][lead];int x=flag? 15:a[pos];int ans=0;for(int i=0;i<=x;i++)(ans+=dfs(pos+1,(!lead&&i==0)? state:state|(1<<i),flag||i<x,lead||i!=0))%=mod;f[pos][cnt][flag][lead]=ans;return ans;
}int main()
{// ios::sync_with_stdio(false);
// cin.tie(0);scanf("%s%d",s+1,&k);n=strlen(s+1);for(int i=1;i<=n;i++)if(s[i]>='A'&&s[i]<='Z') a[i]=s[i]-'A'+10;else a[i]=s[i]-'0';memset(f,-1,sizeof(f));printf("%d",dfs(1,0,0,0));return 0;
}
/**/
f[pos][pre]f[pos][pre]f[pos][pre]的做法。
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=200010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n,k;
int a[N];
char s[N];
int f[N][20];int dfs(int pos,int state,int flag,int lead)
{int cnt=__builtin_popcount(state);if(cnt>k) return 0;if(pos==n+1) return cnt==k&&lead;if(flag&&lead&&f[pos][cnt]!=-1) return f[pos][cnt];int x=flag? 15:a[pos];int ans=0;for(int i=0;i<=x;i++)(ans+=dfs(pos+1,(!lead&&i==0)? state:state|(1<<i),flag||i<x,lead||i!=0))%=mod;if(flag&&lead) f[pos][cnt]=ans;return ans;
}int main()
{// ios::sync_with_stdio(false);
// cin.tie(0);scanf("%s%d",s+1,&k);n=strlen(s+1);for(int i=1;i<=n;i++)if(s[i]>='A'&&s[i]<='Z') a[i]=s[i]-'A'+10;else a[i]=s[i]-'0';memset(f,-1,sizeof(f));printf("%d",dfs(1,0,0,0));return 0;
}
/**/
AtCoder Beginner Contest 194 F - Digits Paradise in Hexadecimal 数位dp相关推荐
- AtCoder Beginner Contest 215 F - Dist Max 2
AtCoder Beginner Contest 215 F - Dist Max 2 平面上有一系列的点(xi,yi)(x_i,y_i)(xi,yi),定义两点(xi,yi),(xj,yj)(x ...
- AtCoder Beginner Contest 204 F Hanjo 2
AtCoder Beginner Contest 204 F Hanjo 2 H宽,W长的二维平面上,用1 * 1或者2 * 1的地砖来铺,要求铺满,求出方案数. 数据范围H <= 6, W & ...
- AtCoder Beginner Contest 170 F. Pond Skater
AtCoder Beginner Contest 170 F. Pond Skater 题目链接 第一次碰到会写的 F,真的哭辽/(ㄒoㄒ)/~~,BFS+剪枝 题目有几个坑点: 1.初始化,我们直接 ...
- AtCoder Beginner Contest 167 F.Bracket Sequencing
AtCoder Beginner Contest 167 F.Bracket Sequencing 题目链接 判断括号匹配的字符串问题~ 首先给出的所有字符串的左右括号数是要匹配的,这个很好判断,用一 ...
- AtCoder Beginner Contest 187 F.Close Group Editorial
AtCoder Beginner Contest 187 F.Close Group Editorial 题目链接 状压DP~ 如果对边暴力的话复杂度约为 21502^{150}2150,显然不可取, ...
- AtCoder Beginner Contest 264 G.String Fair(最短路/暴力dp 补写法)
题目 n(n<=18278)个串,第i个串Ti(Ti为纯小写字母串且长度不超过3), 得分Pi(-1e9<=Pi<=1e9),表示只要子串中出现一次Ti,就会获得Pi的得分 对于你可 ...
- AtCoder Beginner Contest 192 F - Potion 背包dp
传送门 题意: 给你nnn个数,让后让你选出来kkk个AAA,把他们求和,之后再递增kkk直到正好达到xxx,求最小的递增次数. 思路: 转化一下题意就是求∑A=x(modlen)\sum A=x(\ ...
- Caddi Programming Contest 2021(AtCoder Beginner Contest 193) F.Zebraness
题目链接 Problem Statement We have a grid with N horizontal rows and N vertical columns. Let (i,j) denot ...
- AtCoder Beginner Contest 187 F - Close Group
https://atcoder.jp/contests/abc187/tasks/abc187_f 有点像小米决赛的G题啊,所以就秒了 dp[i]表示i这个状压状态,最少可以是多少连通块组成 先预处理 ...
最新文章
- 新年开工——相关性分析了解一下?
- 符号说明表怎么做_教会你的孩子正确使用标点符号
- python2.7可以同时连接两个数据库吗
- stm32F103的systick时间不准终于找到原因了
- java文字转语音支持ubuntu系统_微信内测语音进度条,60秒语音终于有救了?腾讯:并没有...
- flutter调用api_如何在Flutter(REST API)中进行API调用
- JVM核心——JVM运行和类加载全过程
- hihocoder第218周:AC自动机
- WinEdt10注册码
- AndroidStudio3.0多渠道打包
- python不同版本切换_Python版本切换,python,的
- CMMI3过程改进项目计划
- Quartz_2.2.X学习系列四: Tutorials - Lesson 4: More About Triggers
- php获取指定日期的节假日信息
- MySQL主从之GTID主从
- c语言花样编程,C语言表达式的花样表达
- 搜题公众号制作简单教学
- uni-app 小程序分段器tab 的 实现
- ISIC-2017 和 PH2 皮肤镜图像分割数据集
- 手机POS机支付能否挑战支付宝、微信?
热门文章
- 潍坊学院计算机系崔玲玲,人工免疫算法在引水工程中的应用.pdf
- php yii 插入,Yii2 批量插入、更新数据实例
- 地球上最快的速度......
- 全球孩子迷恋手机/iPad,其实罪魁祸首是父母!
- 好好珍惜今生,不要期待来世……
- 用 Python 实现打飞机
- 请问:如何写出没有BUG的代码?
- 如何判断程序员是在装逼还是有真本事?
- 计算机如何实现共享接入,局域网内电脑实现共享设置方法
- python中线程和进程_python中线程和进程的简单了解