论此题循环式数位 dp 代码
查看原帖
论此题循环式数位 dp 代码
1386960
one_of_the_person楼主2025/7/24 18:53

这是我的代码

#include<bits/stdc++.h>
#define int __int128
#define N 2000000
#define Mod 1000000007
using namespace std;
struct Node{int x,y,s,t;};
bool operator>(Node const &x,Node const &y){
	return x.x*x.y>y.x*y.y;
}
bool operator<(Node const &x,Node const &y){
	return x.x*x.y<y.x*y.y;
}
int n,k,f[N+5]={},ans=0,ux,dp[15][40][30][15][15]={},dp2[15][40][30][15][15]={},tot=0,cnt[40][30][15][15]={};
Node u;
priority_queue<Node>p;
int read(){
	int f=1,g=0;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while('0'<=ch&&ch<='9'){
		g=g*10+ch-'0';
		ch=getchar();
	}
	return f*g;
}
void print(int x){
	if(x<0){
		putchar('-');
		x*=-1;
	}
	if(x>9)print(x/10);
	putchar(x%10+'0');
	return;
}
int getsum(int x){
	int sum=1;
	while(x)sum*=(x%10),x/=10;
	return sum;
}
bool cmp(int x,int y){
	return x>y;
}
int fpow(int x,int y){
	if(!y)return 1;
	if(y&1)return fpow(x*x,y>>1)*x;
	return fpow(x*x,y>>1);
}
int npow(int x,int y){
	return x%fpow(10,y+1);
}
main(){ 
	// freopen("gold.in","r",stdin);
	// freopen("gold.out","w",stdout);
	n=read(),k=read();
	dp[0][0][0][0][0]=1;
	for(int i=0;i<13;i++)for(int a2=0;a2<=39;a2++)for(int a3=0;a3<=26;a3++)for(int a5=0;a5<=13;a5++)for(int a7=0;a7<=13;a7++){
        if(dp[i][a2][a3][a5][a7]<0){
            printf("sdfasdfdfsfsdfsd");
            return 0;
        }
		if(!dp[i][a2][a3][a5][a7])continue;
		dp[i+1][a2][a3][a5][a7]=(dp[i+1][a2][a3][a5][a7]+dp[i][a2][a3][a5][a7]);
		dp[i+1][a2+1][a3][a5][a7]=(dp[i+1][a2+1][a3][a5][a7]+dp[i][a2][a3][a5][a7]);
		dp[i+1][a2][a3+1][a5][a7]=(dp[i+1][a2][a3+1][a5][a7]+dp[i][a2][a3][a5][a7]);
		dp[i+1][a2+2][a3][a5][a7]=(dp[i+1][a2+2][a3][a5][a7]+dp[i][a2][a3][a5][a7]);
		dp[i+1][a2][a3][a5+1][a7]=(dp[i+1][a2][a3][a5+1][a7]+dp[i][a2][a3][a5][a7]);
		dp[i+1][a2+1][a3+1][a5][a7]=(dp[i+1][a2+1][a3+1][a5][a7]+dp[i][a2][a3][a5][a7]);
		dp[i+1][a2][a3][a5][a7+1]=(dp[i+1][a2][a3][a5][a7+1]+dp[i][a2][a3][a5][a7]);
        dp[i+1][a2+3][a3][a5][a7]=(dp[i+1][a2+3][a3][a5][a7]+dp[i][a2][a3][a5][a7]);
		dp[i+1][a2][a3+2][a5][a7]=(dp[i+1][a2][a3+2][a5][a7]+dp[i][a2][a3][a5][a7]);
	}
	for(int i=1;i<=13;i++)for(int a2=0;a2<=39;a2++)for(int a3=0;a3<=26;a3++)for(int a5=0;a5<=13;a5++)for(int a7=0;a7<=13;a7++){
		if(fpow(10,i)>n)break;
        if(!dp[i][a2][a3][a5][a7])continue;
		// f[++tot]=dp[i][a2][a3][a5][a7];
        cnt[a2][a3][a5][a7]+=dp[i][a2][a3][a5][a7];
	}
	dp2[0][0][0][0][0]=1;
	for(int i=0;i<13;i++)for(int a2=0;a2<=39;a2++)for(int a3=0;a3<=26;a3++)for(int a5=0;a5<=13;a5++)for(int a7=0;a7<=13;a7++){
        if(dp2[i][a2][a3][a5][a7]<0){
            printf("sdfasdfdfsfsdfsd");
            return 0;
        }
		if(!dp2[i][a2][a3][a5][a7]&&!dp[i][a2][a3][a5][a7])continue;
		if(2ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2][a3][a5][a7]=(dp2[i+1][a2][a3][a5][a7]+dp[i][a2][a3][a5][a7]);
		else if(1ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2][a3][a5][a7]=(dp2[i+1][a2][a3][a5][a7]+dp2[i][a2][a3][a5][a7]);
		if(3ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2+1][a3][a5][a7]=(dp2[i+1][a2+1][a3][a5][a7]+dp[i][a2][a3][a5][a7]);
		else if(2ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2+1][a3][a5][a7]=(dp2[i+1][a2+1][a3][a5][a7]+dp2[i][a2][a3][a5][a7]);
		if(4ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2][a3+1][a5][a7]=(dp2[i+1][a2][a3+1][a5][a7]+dp[i][a2][a3][a5][a7]);
		else if(3ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2][a3+1][a5][a7]=(dp2[i+1][a2][a3+1][a5][a7]+dp2[i][a2][a3][a5][a7]);
		if(5ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2+2][a3][a5][a7]=(dp2[i+1][a2+2][a3][a5][a7]+dp[i][a2][a3][a5][a7]);
		else if(4ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2+2][a3][a5][a7]=(dp2[i+1][a2+2][a3][a5][a7]+dp2[i][a2][a3][a5][a7]);
		if(6ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2][a3][a5+1][a7]=(dp2[i+1][a2][a3][a5+1][a7]+dp[i][a2][a3][a5][a7]);
		else if(5ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2][a3][a5+1][a7]=(dp2[i+1][a2][a3][a5+1][a7]+dp2[i][a2][a3][a5][a7]);
		if(7ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2+1][a3+1][a5][a7]=(dp2[i+1][a2+1][a3+1][a5][a7]+dp[i][a2][a3][a5][a7]);
		else if(6ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2+1][a3+1][a5][a7]=(dp2[i+1][a2+1][a3+1][a5][a7]+dp2[i][a2][a3][a5][a7]);
		if(8ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2][a3][a5][a7+1]=(dp2[i+1][a2][a3][a5][a7+1]+dp[i][a2][a3][a5][a7]);
		else if(7ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2][a3][a5][a7+1]=(dp2[i+1][a2][a3][a5][a7+1]+dp2[i][a2][a3][a5][a7]);
        if(9ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2+3][a3][a5][a7]=(dp2[i+1][a2+3][a3][a5][a7+1]+dp[i][a2][a3][a5][a7]);
		else if(8ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2+3][a3][a5][a7]=(dp2[i+1][a2+3][a3][a5][a7]+dp2[i][a2][a3][a5][a7]);
		if(10ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2][a3+2][a5][a7]=(dp2[i+1][a2][a3+2][a5][a7]+dp[i][a2][a3][a5][a7]);
		else if(9ll*fpow(10,i)<=npow(n,i))dp2[i+1][a2][a3+2][a5][a7]=(dp2[i+1][a2][a3+2][a5][a7]+dp2[i][a2][a3][a5][a7]);
	}
	for(int i=1;i<13;i++)for(int a2=0;a2<=39;a2++)for(int a3=0;a3<=26;a3++)for(int a5=0;a5<=13;a5++)for(int a7=0;a7<=13;a7++){
		if(fpow(10,i)<=n)continue;
		if(fpow(10,i-1)>n)break;
        if(!dp2[i][a2][a3][a5][a7])continue;
		// f[++tot]=dp2[i][a2][a3][a5][a7];
        cnt[a2][a3][a5][a7]+=dp2[i][a2][a3][a5][a7];
	}
    for(int a2=0;a2<=39;a2++)for(int a3=0;a3<=26;a3++)for(int a5=0;a5<=13;a5++)for(int a7=0;a7<=13;a7++){
        if(cnt[a2][a3][a5][a7]<0){
            printf("sdfasdfdfsfsdfsd");
            return 0;
        }
        if(!cnt[a2][a3][a5][a7])continue;
        f[++tot]=cnt[a2][a3][a5][a7];
    }
//	for(int i=1;i<=n;i++){
//		ux=getsum(i);
//		if(ux>0&&ux<=n)f[ux]++;
//	}
	sort(f+1,f+1+tot,cmp);
	for(int i=1;i<=tot;i++)p.push({f[i],f[i],i,i});
//	cout<<(long long)p.top().s<<"\n";
	while(k){
		u=p.top(),p.pop();
//		cout<<u.x<<" "<<u.y<<" "<<u.s<<" "<<u.t<<" "<<ans<<" "<<k<<"\n";
		if(u.s!=u.t&&k>1)ans=(ans+u.x*u.y%Mod*2%Mod)%Mod,k-=2;
		else ans=(ans+u.x*u.y%Mod)%Mod,k-=1;
		if(u.t<n)p.push({f[u.s],f[u.t+1],u.s,u.t+1});
	}
	print(ans);
	return 0;
}

十分简洁,如何让代码更简洁?

2025/7/24 18:53
加载中...