Ignatius and the Princess III(점진)

1419 단어
정수 구분 문제는 고전적인 귀속 문제이다.
p[n][m]는 정수 n의 m를 n=x1+x2+x3+...+로 나눈다x;그 중에서 xi의 최대치는 m보다 작다.
그러면 문제를 어떻게 그 하위 문제로 전환시킬 것인가에 대해 토론해 봅시다.
1. m=1 또는 n=1일 때 분명히 dp[n][m]=1;
2. n3. n=m일 때 두 가지 상황을 고려한다
3.1 구분된 수에 m가 포함될 때 dp[n][m]=1;
3.2 구분된 수가 m를 포함하지 않을 때 문제는 정수 n의 m-1의 구분 dp[n][m]=dp[n][m-1]로 전환한다.
4、n>m일 때도 두 가지 상황으로 나뉜다
4.1 구분된 수에 m가 포함될 때 문제는 정수 n-m의 m로 구분 dp[n][m]=dp[n-m][m]로 전환한다.
4.2 구분된 수에 m가 포함되지 않을 때 문제는 정수 n의 m-1의 구분 dp[n][m]=dp[n][m-1]로 전환한다.
요약:
dp(n, m)=   1;(n=1 또는 m=1)
                             dp(n, n);                        (n                             1+dp(n, m-1);                (n=m)
                             dp(n-m,m)+dp(n,m-1);      (n>m)
직접 귀환은 시간을 초과할 수 있습니다. 그러면 우리는 기억화 검색의 방식으로 해결하거나 추이를 할 수 있습니다.
다음은 메모리 검색 코드입니다.
#include <stdio.h>
#include <string.h>
#define maxn 125
int dp[maxn][maxn];
int dfs(int n,int m)
{

	int i,j;
	if(dp[n][m]!=-1)	return dp[n][m];
	if(n==1 || m==1)	return 1;
	if(n<m)	dp[n][m]=dfs(n,n);
	else if(n==m)	dp[n][m]=1+dfs(n,m-1);
	else if(n>m)	dp[n][m]=dfs(n-m,m)+dfs(n,m-1);
	return dp[n][m];
		
}
int main()
{
	int N,sum;
	memset(dp,-1,sizeof(dp));

	while(scanf("%d",&N)==1)
	{
		sum=dfs(N,N);
		printf("%d
",sum); } }

좋은 웹페이지 즐겨찾기