1. 程式人生 > >神奇的四次方數

神奇的四次方數

題面(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;
}

沒有水印了,,,這輩子可能都沒有了、、、、