AtCoder Beginner Contest 194 F - Digits Paradise in Hexadecimal

https://atcoder.jp/contests/abc194/tasks/abc194_f

It’s too bad and I have encountered a digital DP problem that I can’t

The key to this question is that we don’t need to store the currently used numbers in the dp array.

Just make dp[pos][cnt][up][lead]=dp[Which one is enumerated][There are several different numbers][Whether it is against the upper bound][Whether there is a non-zero bit in front]

As long as pos, up, lead are right, then for different st have the same cnt, their answer is the same, so the specific st does not need to be stored in dp, only the number of bits is needed.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxl=2e5+10;
const int mod=1e9+7;

int n,k;
int a[maxl];
ll dp[maxl][17][2][2];
char s[maxl];

inline ll dfs(int pos,int st,bool up,bool lead)
{
	int cnt=__builtin_popcount(st);
	if(cnt>k) return 0;
	if(pos>n) return cnt==k && lead;
	ll &ret=dp[pos][cnt][up][lead];
	if(ret!=-1)
		return ret;
	ret=0;
	int r=up?a[pos]:15;
	for(int i=0;i<=r;i++)
		ret=(ret+dfs(pos+1,(!i&&!lead)?st:st|(1<<i),up&&(i==r),lead|i))%mod;
	return ret;
}

int main()
{
	scanf("%s",s+1);scanf("%d",&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(dp,-1,sizeof(dp));
	printf("%lld\n",dfs(1,0,1,0));
	return 0;
}

 

Guess you like

Origin blog.csdn.net/liufengwei1/article/details/114609516