HDU 5646

DZY Loves Partition

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 815    Accepted Submission(s): 298


Problem Description
DZY loves partitioning numbers. He wants to know whether it is possible to partition n into the sum of exactly k distinct positive integers.

After some thinking he finds this problem is Too Simple. So he decides to maximize the product of these k numbers. Can you help him?

The answer may be large. Please output it modulo 109+7 .
 
Input
First line contains t denoting the number of testcases.

t testcases follow. Each testcase contains two positive integers n,k in a line.

(1t50,2n,k109 )
 
Output
For each testcase, if such partition does not exist, please output 1 . Otherwise output the maximum product mudulo 109+7 .
 
Sample Input
4
3 4
3 2
9 3
666666 2
 
Sample Output
-1
2
2
4
110888111
Hint
In 1st testcase, there is no valid partition. In 2nd testcase, the partition is $3=1+2$. Answer is $1 imes 2 = 2$. In 3rd testcase, the partition is $9=2+3+4$. Answer is $2 imes 3 imes 4 = 24$. Note that $9=3+3+3$ is not a valid partition, because it has repetition. In 4th testcase, the partition is $666666=333332+333334$. Answer is $333332 imes 333334= 111110888888$. Remember to output it mudulo $10^9 + 7$, which is $110888111$.
 
Source
 
题意:t组数据 将n分为k个数的和 使得 这k个数的乘积最大(k个数不能重复) 输出这个数
官方题解

sum(a,k)=a+(a+1)+⋯+(a+k−1)

首先,有解的充要条件是sum(1,k)≤n(如果没取到等号的话把最后一个k扩大就能得到合法解)。

然后观察最优解的性质,它一定是一段连续数字,或者两段连续数字中间只间隔1个数。这是因为1≤a<=b−2时有ab<(a+1)(b−1)如果没有满足上述条件的话,我们总可以把最左边那段的最右一个数字作为a,最右边那段的最左一个数字作为b,调整使得乘积更大。

可以发现这个条件能够唯一确定n的划分,只要用除法算出唯一的a使得sum(a,k)≤n<sum(a+1,k)就可以得到首项了。

理解我yan代码  先排列一个k位的首项为1 的等差数列 将剩下的数 优先靠右分配

       
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<map>
 6 using namespace std;
 7 #define mod 1000000007
 8 #define  ll __int64
 9 ll T,n,k,f;
10 ll ans = 1;
11 int main() {
12     scanf("%I64d",&T);
13     while(T--) 
14     {
15         scanf("%I64d%I64d",&n,&k);
16         ans = 1;
17         if(k==1) 
18         {
19             cout<<n<<endl;
20             continue;
21         }
22         if(n<k) 
23         cout<<-1<<endl;
24         else 
25         {
26             n = n-(1+k)*k/2;//每个只能出现一次 
27             if(n<0) 
28         {
29                 cout<<-1<<endl;continue;
30         }
31             if(n==0) 
32             {
33                 for(int i=1;i<=k;i++) 
34                 ans=(ans*i)%mod;
35                 cout<<ans<<endl;
36                 continue;
37             }
38            for(int i=k;i>k-n%k;i--)
39                ans=(ans*(n/k+1+i))%mod;
40            for(int i=k-n%k;i>=1;i--) 
41                 ans=(ans*(n/k+i))%mod;
42            cout<<ans<<endl;
43         }
44     }
45 }
View Code
 
 
原文地址:https://www.cnblogs.com/hsd-/p/5303986.html