1. 程式人生 > >整數拆分並且乘積最大問題

整數拆分並且乘積最大問題

第二次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;
其實是想證明的但是太麻煩了還是舉例吧