hdu5646 DZY Loves Partition 数学


ZY Loves Partition

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


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 .
 

题意:给定数n和数k,使k个不同的数的和味n,且要求这k个数的乘积尽可能大,问乘积对1e9+7取模后是多少。

解:若sum(1,k)已经大于n则必无解,否则可通过对最大数增加一定能得到解。

当有解时:由基本不等式的(a1+a2+...+an)*1/n>=(a1*a2...*an)^1/n.挡a1,a2...相等时取等号,要使乘积尽可能大,那么需要这n个数尽可能接近,于是求连续最大和sum(begin,begin+k-1)<=n,然后把n-sum(begin.begin+k-1)剩下的从大到小分配即可。

AC代码:

//************************************************************************//
//*Author : Handsome How                                                 *//
//************************************************************************//
//#pragma comment(linker, "/STA    CK:1024000000,1024000000")
#pragma warning(disable:4996) 
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>                                                
#include <cassert>
#if defined(_MSC_VER) || __cplusplus > 199711L
#define aut(r,v) auto r = (v)
#else
#define aut(r,v) __typeof(v) r = (v)
#endif
#define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it)
#define fur(i,a,b) for(int i=(a);i<=(b);i++)
#define furr(i,a,b) for(int i=(a);i>=(b);i--)
#define cl(a) memset((a),0,sizeof(a))
using namespace std;
typedef long long LL;
//----------------------------------------------------
const LL mod = 1e9 + 7;

int main()
{
    //freopen("E:\\data.in", "r", stdin);
    ios :: sync_with_stdio(false);
    int T;
    scanf("%d", &T);
    while (T--)
    {
        LL n, k;
        scanf("%I64d%I64d", &n, &k);
        LL t;
        t = (1 + k)*k / 2;
        if(t>n) {
            printf("-1\n");
            continue;
        }
        LL begin;
        begin = (2 * n / k + 1 - k) / 2;
        LL res =n - (begin + begin + k - 1)*k / 2;
        LL real = 1;
        LL end = begin + k - 1;
        while (res)
        {
            real *= (end + 1);
            real %= mod;
            res--;
            end--;
        }
        for (LL i = begin; i <= end; i++) {
            real *= i;
            real %= mod;
        }
        printf("%I64d\n",real);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值