Division of numbers [codevs], [golden question], [dynamic programming]

Keywords: Programming

Division of numbers

Train of thought: in this question, I tried to use dp written recursively to build a table by memory.

In dp [x] [y] [z], X represents the number to be allocated, Y represents the score in the future, and z represents the remaining allocation opportunities.

 

dp equation is dp[x][y][z] = sum {dp[x-k][k][z-1]} (k is from y to 1) (Note: K starts from y, and x-k < 0 needs to be continue d.)

 

We need to pay attention to two situations: incomplete distribution and insufficient distribution.

When z > x, not enough points, dp is 0. When z==x, just enough points, dp[x][y][z]=1;

When x > y * Z, the allocation is endless, dp is 0. When equal, dp[x][y][z]=1;

 

If z = = 0 & & x = = 0, the allocation is complete, return 1;

#include<iostream>
using namespace std;
int n,k; 
int dp[201][201][7];
int dfs(int x,int y,int z){
	if(z==0&&x==0)return 1;
	if(dp[x][y][z]!=-1)return dp[x][y][z];
	
	if(z>x){
		dp[x][y][z]=0;
	//	cout<<x<<" "<<y<<" "<<z<<": "<<0<<endl;
		return 0;	
	}
	else if(z==x){
		dp[x][y][z]=1;
	//	cout<<x<<" "<<y<<" "<<z<<": "<<1<<endl;
		return 1;
	}
	else if(x>y*z){
		dp[x][y][z]=0;
	//	cout<<x<<" "<<y<<" "<<z<<": "<<0<<endl;
		return 0;
	}
	else if(x==y*z){
		dp[x][y][z]=1;
	//	cout<<x<<" "<<y<<" "<<z<<": "<<1<<endl;
		return 1;
	}
	
	int res=0;
	for(int k1=y;k1>=1;k1--){
		if(x-k1<0)continue;
		res+=dfs(x-k1,k1,z-1);
	}
	
	dp[x][y][z]=res;
//	cout<<x<<" "<<y<<" "<<z<<": "<<res<<endl;
	return dp[x][y][z];
}


int main(){
	cin>>n>>k;
	for(int i=0;i<=n;i++){
		for(int j=0;j<=n;j++){
			for(int l=0;l<=k;l++){
				dp[i][j][l]=-1;
			}
		}
	}	
	cout<<dfs(n,n,k)<<endl;
	return 0;
}

 

 

 

Posted by JVassie on Sat, 14 Dec 2019 11:03:48 -0800