数位DP练习

50 篇文章 0 订阅
4 篇文章 0 订阅

HDU 4734
题目传送门

代码:

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

const int maxn=10000+100;

int dp[20][maxn],bit[20];
int all; 

int DFS(int pos,int statu,bool limit){
	
	if(pos==-1) return statu<=all;
	if(statu>all) return 0;
	if(!limit && dp[pos][all-statu]!=-1) return dp[pos][all-statu];
	int end=limit?bit[pos]:9;
	int cnt=0;
	for(int i=0;i<=end;i++){
		
		cnt+=DFS(pos-1,statu+(i<<pos),limit && i==end);
	}
	return limit?cnt:dp[pos][all-statu]=cnt;
}

int slove(int num){
	
	int pos=0;
	while(num){
		
		bit[pos++]=num%10;
		num/=10;
	}
	return DFS(pos-1,0,true);
}

int main(){
	
	int T,C=0;
	scanf("%d",&T);
	memset(dp,-1,sizeof(dp));
	while(T--){
		
		int a,b;
		scanf("%d%d",&a,&b);
		int tmp=1;
		all=0;
		while(a){
			
			all+=(a%10)*tmp;
			a/=10;
			tmp*=2;
		}
		printf("Case #%d: %d\n",++C,slove(b));
	}
}

HDU 3709
题目传送门

代码:

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

typedef long long ll;
const int maxn=2000+100;

ll dp[20][20][maxn];
int bit[20];

ll DFS(int pos,int center,int cnt,bool limit){
	
	if(pos==-1) return cnt==0;
	if(cnt<0) return 0;
	if(!limit && dp[pos][center][cnt]!=-1) return dp[pos][center][cnt];
	int end=limit?bit[pos]:9;
	ll ans=0;
	for(int i=0;i<=end;i++){
		
		ans+=DFS(pos-1,center,cnt+i*(pos-center),limit && i==end);
	}
	return limit?ans:dp[pos][center][cnt]=ans;
}

ll slove(ll num){
	
	int pos=0;
	while(num){
		
		bit[pos++]=num%10;
		num/=10;
	}
	ll ans=0;
	for(int i=0;i<pos;i++) ans+=DFS(pos-1,i,0,true);
	return ans-(pos-1);
}

int main(){
	
	int T;
	scanf("%d",&T);
	memset(dp,-1,sizeof(dp));
	while(T--){
		
		ll a,b;
		scanf("%lld%lld",&a,&b);
		printf("%lld\n",slove(b)-slove(a-1)); 
	}
}

HDU 3652
题目传送门

代码:

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

int dp[15][20][10][2];
int bit[15];

int DFS(int pos,bool isok,int statu,int endbit,int limit){
	
	if(pos==-1) return isok&&statu%13==0;
	if(!limit && dp[pos][statu][endbit][isok]!=-1) return dp[pos][statu][endbit][isok];  
	int end=limit?bit[pos]:9;
	int ans=0; 
	for(int i=0;i<=end;i++){
		
		ans+=DFS(pos-1,isok || (i==3 && endbit==1),(statu*10+i)%13,i,limit && i==end);
	}
	return limit?ans:dp[pos][statu][endbit][isok]=ans;
}

int slove(int num){
	
	int pos=0;
	while(num){
		
		bit[pos++]=num%10;
		num/=10;
	}
	return DFS(pos-1,false,0,0,true);
}

int main(){
	
	memset(dp,-1,sizeof(dp));
	int n;
	while(scanf("%d",&n)==1){
		
		printf("%d\n",slove(n));
	}
} 

HDU 4352
题目传送门

代码:

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

typedef long long ll;
const int maxn=1<<10;

ll dp[25][maxn][15];
ll l,r;
int k;
int bit[25];

int get(int x,int statu){
	
	for(int i=x;i<10;i++) if(statu&(1<<i)) return (statu^(1<<i))|(1<<x);
	return statu|(1<<x);
}

int getNum(int num){
	
	int cnt=0;
	while(num){
		
		if(num&1) cnt++;
		num>>=1;
	}
	return cnt;
}

ll DFS(int pos,int statu,bool limit,bool prezero){
	
	if(pos==-1) return getNum(statu)==k;
	if(!limit && dp[pos][statu][k]!=-1) return dp[pos][statu][k];
	int end=limit?bit[pos]:9;
	ll ans=0;
	for(int i=0;i<=end;i++){
		
		ans+=DFS(pos-1,(prezero && i==0)?0:get(i,statu),limit && i==end,prezero && i==0); 
	}
	return limit?ans:dp[pos][statu][k]=ans;
}

ll slove(ll num){
	
	int pos=0;
	while(num){
		
		bit[pos++]=num%10;
		num/=10;
	}
	return DFS(pos-1,0,true,true);
}

int main(){
	
	int T,C=0;
	scanf("%d",&T);
	memset(dp,-1,sizeof(dp));
	while(T--){
		
		scanf("%lld%lld%d",&l,&r,&k);
		printf("Case #%d: %lld\n",++C,slove(r)-slove(l-1));
	}
} 

HDU 5898
题目传送门

代码:

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

typedef long long ll;

ll dp[25][2][25][2][2];
int bit[25];

ll DFS(int pos,bool endbit,int len,bool preisok,bool prezero,bool limit){
	
	if(pos==-1) return preisok && (((endbit%2+1)%2)==len%2);
	if(!limit && dp[pos][endbit][len][preisok][prezero]!=-1) return dp[pos][endbit][len][preisok][prezero];
	int end=limit?bit[pos]:9;
	ll ans=0;
	for(int i=0;i<=end;i++){
		
		int newlen;
		bool newprezero=(prezero && i==0);
		bool newpreisok=preisok;
		if(newprezero) newlen=0;
		else if(prezero) newlen=1;
		else newlen=(endbit==(i%2))?len+1:1;
		if(!prezero && endbit!=(i%2)) newpreisok=(preisok&&(((endbit%2+1)%2)==len%2));
		ans+=DFS(pos-1,i%2,newlen,newpreisok,newprezero,limit && i==end);
	}
	return limit?ans:dp[pos][endbit][len][preisok][prezero]=ans;
}

ll slove(ll num){
	
	int pos=0;
	while(num){
		
		bit[pos++]=num%10;
		num/=10;
	}
	return DFS(pos-1,0,0,true,true,true);
}

int main(){
	
	int T,C=0;
	scanf("%d",&T);
	memset(dp,-1,sizeof(dp));
	while(T--){
		
		ll l,r;
		scanf("%lld%lld",&l,&r);
		printf("Case #%d: %lld\n",++C,slove(r)-slove(l-1));
	}
}

HDU 5179
题目传送门

代码:

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

int dp[15][10][2][2];
int bit[15];

int DFS(int pos,int endbit,int isok,bool prezero,int limit){
	
	if(pos==-1) return isok;
	if(!limit && dp[pos][endbit][isok][prezero]!=-1) return dp[pos][endbit][isok][prezero];
	int end=limit?bit[pos]:9;
	int ans=0;
	for(int i=0;i<=end;i++){
		
		bool newisok;
		if(prezero) newisok=isok;
		else if(i==0) newisok=false;
		else if(i>endbit || endbit%i) newisok=false;
		else newisok=isok;
		ans+=DFS(pos-1,i,newisok,prezero && i==0,limit && i==end);
	}
	return limit?ans:dp[pos][endbit][isok][prezero]=ans;
}

int slove(int num){
	
	int pos=0;
	while(num){
		
		bit[pos++]=num%10;
		num/=10;
	}
	return DFS(pos-1,0,true,true,true);
}

int main(){
	
	int T;
	scanf("%d",&T);
	memset(dp,-1,sizeof(dp));
	while(T--){
		
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",slove(r)-slove(l-1));
	}
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ITKaven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值