整數拆分並且乘積最大問題
阿新 • • 發佈:2018-12-24
第二次BC,還是被第二題難住了,拆分整數的題
DZY喜歡拆分數字。他想知道能否n拆成恰好k個不重複的正整數之和。
思考了一會兒之後他發現這個題太簡單,於是他想要最大化這k個正整數的乘積。你能幫幫他嗎?
由於答案可能很大,請模1e9+7
輸出。
輸入描述
第一行t,表示有t組資料。
接下來t組資料。每組資料包含一行兩個正整數n,k
(1≤t≤50,2≤n,k≤10^9)
輸出描述
對於每個資料,如果不存在拆分方案,輸出−1-1−1;否則輸出最大乘積模10^9 + 7
輸入樣例
4
3 4
3 2
9 3
666666 2
輸出樣例
-1
2
24
110888111
#include<iostream>
#include<vector>
using namespace std;
const int mod = 1e9 + 7;
int main()
{
int T;
cin >> T;
while (T--)
{
long long n, k;
cin >> n >> k;
if (n <(k*(k + 1)) / 2)
{
cout << -1 << endl;
}
else
{
n = n - k*(k + 1) / 2;
vector<long long> num(k + 1);
for (int a = 1;a <= k;a++)
{
num[a] = (n / k) + a;
}
for (int a = k;a >k - n%k;a--)
{
num[a]++;
}
long long sum = 1;
for (int a = 1;a <= k;a++)
{
sum = sum*num[a] % mod;
}
cout << sum%mod << endl;
}
}
return 0;
}
我的思路是看到拆分成為k個不相等整數,其乘積最大,首先想到的是他們每個數之間的差一定要是最小的,最好是1,而看到k的範圍小於19的九次方以後,就要考慮是不是該用long long型別的整形了,在這裡卡了我好久,以後需要注意。因為是k個連續的整數是最低要求,起碼也要從一開始,因此n一定要大於等於k(k+1)/2才可以,後期要把這個值重新分配給每個數作為權重,因此暫時減掉,所以每個數的基礎值的總額現在就是n了,所以再分成k份。現在考慮剩下的餘數問題,因為前面的數都是連續的,因此無論加上多少都不對,都會變成重複的數,所以考慮從後面向前加過去。
然後整理一個關於模的運算
(a*b*c*d*e….)%p=(a%p*b)%p*c)%p……
舉例:設a=ps+y,b=po+e
(ab)%p=(sop^2+ye+pse+ypo)%p=ye;
(a%p*b)%p=(ypo+ye)%p=ye;
其實是想證明的但是太麻煩了還是舉例吧