数位DP练习

HDU 4734
题目传送门

代码:

#include
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<

HDU 3709
题目传送门

代码:

#include
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

HDU 3652
题目传送门

代码:

#include
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
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<>=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
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
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));
	}
} 

你可能感兴趣的:(HDU,ACM)