完全平方数求最小

问题:给定一个正数n:得到最少的完全平方数组成的正数?

解法一:用贪心思想,每次得到最大的完全平方数,直到平方数为1.

但是这种解法没有得到最少平方数。

int tanxin(int n)
{
	int t = n;
	int num = 0,sum=0;
	int i = (int)sqrt(t);
	while (i >= 1)
	{
		if (sum+i*i>t)
			break;
		else if(sum+i*i==t)
		{
			cout << (i*i) ;
			num++;
			break;
		}	
		else
		{
			cout << (i*i) << "+";
			sum += i * i;
			i = sqrt(t-sum);
			num++;
		}
	}
	return num;
}

思想:

易知f(1)=1;f(2)=2;f(3)=3;
当n=某一个数的平方时,易知f(n)=1;

当n=6时,f(6)的情况有2种——分别是f(1)+f(6-1)和f(4)+f(6-4),即f(1)+f(5)和f(4)+f(2)。那么f(6)的值便是这两者的最小值,即min( f(1)+f(5) , f(4)+f(2) );
情况1:f(1)的值=1,那f(5)的值等于多少呢?我们可以继续往下推:f(5)的情况有2种:f(1)+f(4)和f(4)+f(1);
情况1.1:f(1)=1,f(4)=1;那么f(5)=2;
情况1.2:f(5)=2;
最终f(5)的值为情况1.1和1.2中的最小值,即f(5)=2;
那么情况1的结构便是f(6)=3;
同理可计算出情况2的结果
…(此处省略)
 

解法二:递归(可得最少数)

int find_min(int n)
{
	if (n <= 0)
		return 0;
	int  min = INT_MAX;;
	for (int i = 1; i <= sqrt(n); i++)
	{
		int t = 1 + find_min(n - i * i);
		if (min > t)
			min = t;
	}
	return min;
}

解法三:记忆递归(可得最少数)第二种的改进

int mfind_min(int n)
{
	if (b[n] != -1)
		return b[n];
	if (n < 0)
		return 0;
	if (n == 0)
	{
		b[n] = 0;
		return b[n];
	}
	int min = INT_MAX;;
	for (int i = 1; i <= sqrt(n); i++)
	{
		int t= 1 + mfind_min(n - i * i);
		if (min > t)
			min = t;
		b[n] = t;
	}
	return b[n];
}

解法三:dp(从下到上)

int dp(int n)
{
	b[0] = 0;
	for (int j = 1; j <= n; j++)
	{
		int min = INT_MAX;
		for (int i = 1; i <= sqrt(j); i++)
		{
			int t = 1 + b(j - i * i);
			if (min > t)
				min = t;
		}
		b[j] = min;
	}
	return b[n];
}
发布了98 篇原创文章 · 获赞 1 · 访问量 4497

猜你喜欢

转载自blog.csdn.net/weixin_40823740/article/details/103125127