神奇的四次方數
阿新 • • 發佈:2018-12-22
題面(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; }
沒有水印了,,,這輩子可能都沒有了、、、、