題目描述
已知若干個正整數的和為s,求這若干個正整數的最小公倍數的最大值。
輸入
第一行乙個整數t,表示測試資料的組數。
接下來t行,每行包括乙個正整數s,表示若干個正整數的和為s。
輸出
輸出t行,每行包括乙個整數,表示和為s的若干個正整數的最小公倍數的最大值。
樣例輸入2
47樣例輸出4
12資料範圍限制
樣例中第一組資料s=4,它能分解成s=1+1+1+1,s=1+1+2,s=1+3,s=2+2,s=4,很明顯s=4時最小公倍數為4,是所有情況中最小公倍數最大的;第二組資料s=7,它能分解成s=3+4,3和4的最小公倍數是12,也是所有情況中最小公倍數最大的。
提示
40%的資料:s≤100;
80%的資料:s≤330,結果不會超過long long型別;
100%的資料:2≤s≤500,t≤10,結果不會超過25位整數。
正解
首先要證明選的數只能是質數的任意次冪。
證明非常簡單,因為最小的質數是二,而對於任意的兩個質數x1、x2,他們的冪次為y1、y2,都有
x1y1+x2y2y1乘x2y2
也就是說,選任意的合數都不如選它的分解質因數合算。
比如選24,不如選2,2,2,3合算。
然後得到了這個證明,我們就可以繼續往下做。
dp:設f[i]表示i最多可以組成多大的數,我們可以得到以下轉移方程:
7 (f[7-22]=f[3])乘22=12
f[i]=max(j∈素數,j^k<=i)
於是,我們可以先預處理出500以內的素數,在進行以上dp,最後處理詢問。
注意:由於dp的無後效性,迴圈i時要倒序。
小技巧
這裡,我們要用高精度,但我們可以用個東西
__int128
這個東西最大是128位數的整型,可以乘,可以加……
但是有一些注意事項
1.不能用cin和scanf輸入,要手寫輸入函式
2.不能用cout和printf輸出,要手寫輸出函式(就像下面一樣)
void
sc(__int128 x)
//輸出**
for(
int i=o;i>=
1;i--
) cout<; cout<}
3.dev—c++上面執行會錯誤,但在評測**上就ok(**例洛谷、gmoj等等)
ac**
#include
#include
using
namespace std;
long
long t,s,o,tot,a[
1005
],b[
1005
],c[
1005];
__int128 f[
1005];
void
sc(__int128 x)
//輸出函式
for(
int i=o;i>=
1;i--
) cout<; cout<}int
main()
for(
int i=
0;i<=
500;i++
)f[i]=1
;//初值
for(
int i=tot;i>=
1;i--
)//質數
for(
int j=
500;j>=b[i]
;j--
)for
(int k=b[i]
;k<=j;k*
=b[i]
)//質數的冪
if(k<=j)f[j]
=max
(f[j]
,f[j-k]
*k);
cin>>t;
for(
int i=
1;i<=t;i++
)return0;
}
2020.03.04模擬賽12(第一題)
2020.03.04模擬賽12(第二題)
2020.03.04模擬賽12(第三題)
2020.03.04模擬賽12(第四題)
2020.03.04模擬賽12(第五題)
2020.03.04模擬賽12(總結)
2020 03 04模擬賽12(總結)
t1 比賽時想到暴力,用了10分鐘,就ac了 t2開始以為是字首和,後來認為是快排,於是找到用快排的解決思路,成功ac t3資料太大,暴力10分,後來聽了討論,知道可以用字首和,就用了字首和和貪心,act4 開始不會做,後來發現可以暴力,o n的長度乘t的長度 不超時 就用了個while,因為會錯,...
集訓模擬賽12
今天虎哥出題變簡單了,今天本來可以寫對三個題,但是 t2 由於沒看題目,改了乙個地方就過了,t3 還把陣列開小了,導致最後少拿了超級多的分。現在後悔也沒用了,吸取教訓吧,看題 該題與題庫中 how many answers are wrong 是一樣的。刁奼接到乙個任務,為稅務部門調查一位商人的賬本...
藍橋杯模擬賽第五場 G 禮物盒
小y 有乙個寬度為 100cm,高度為 20cm,深度為 1cm 的櫃子,如圖。小y 還有 36 個禮物盒,他們的深度都為 1cm。他們對應的寬度和高度如下,單位 cm 11 3 8 12 11 17 16 13 1 14 2 86 10 10 18 17 11 10 15 6 14 5 62 19...