神奇的四次方数

题面(from luogu)
神奇的四次方数
在你的帮助下,v神终于帮同学找到了最合适的大学,接下来就要通知同学了。在班级里负责联络网的是dm同学,于是v神便找到了dm同学,可dm同学正在忙于研究一道有趣的数学题,为了请dm出山,v神只好请你帮忙解决这道题了。

题目描述:将一个整数m分解为n个四次方数的和的形式,要求n最小。例如,m=706,706=5^4 +
3^4,则n=2。

输入格式:
一行,一个整数m。

输出格式:
一行,一个整数n。

输入样例#1:
706
输出样例#1:
2

数据范围:对于30%的数据,m<=5000;对于100%的数据,m<=100,000

题面分析
这是一道很典型的完全背包问题

首先,我们先把问题抽象一下
对一个数,我们要将其分解成多个四次方数,但是这些四次方数从那里来呢?
当然是自己生成了
但是对于这道题,我们只要求出其最大的范围即可了,
这个方面的思路也便是一重for循环,求出边界了

到这里,这道题目已经出来一半了了,因为我们找到了背包问题中所谓的“物品”了
当然,它并没有给出"价值"
这也是需要我们来思考的
但是在这里

这个"价值”不应该很像"花费”吗?
我们用一个数去拆分,在总的使用上面便是要+1的
这不就是“花费”吗?

现在,这道题目,我们已经完全的完成构思了,剩下的便是实践了

代码

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

int f[100009];
int n;
int step;

int main()
{
	memset(f,0x7f,sizeof(f));    //初始化,全部都是无穷大,便于查找最小的
	
	cin>>n;   //输入
	
	for (int i = 1; i <= 20; i++)    //寻找解的范围(最大的边界是在20^4之内的,所以我们只要枚举到20,其实还用不到)
		if (i*i*i*i > n)      //模拟一下  
			{ 
				step = i - 1;    //记录位置
				
				break;
			}
		
	if (step*step*step*step == n)      //判断一下特例
		{
			cout<<1;
			
			return 0;
		}
		
	for (int i = 1; i <= step; i++)     //初始化,所有的四次方数都只需要一步来凑
		f[i*i*i*i] = 1;
		
	//套完全背包的模板	
	for (int i = 1; i <= step; i++)
		for (int j = i*i*i*i; j <= n; j++)
			f[j] = min(f[j],f[j-i*i*i*i] + 1);     
			
	cout<<f[n];   //输出
	
	return 0;
}

没有水印了,,,这辈子可能都没有了、、、、

猜你喜欢

转载自blog.csdn.net/c_uizrp_dzjopkl/article/details/84478834