hdu5646(数学)
Posted chenhuan001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu5646(数学)相关的知识,希望对你有一定的参考价值。
小学数学,脑补
一开始看到这题,猜了个规律想写但是我是拒绝的。
因为我无法证明。
好吧,主要还是小学数学没学好吧。
要理解这题,首先得搞懂一个重要问题。假设C=A+B,怎样选择两个正整数使得A*B最大?
学过小学数学的人都知道,A=C/2,B=C-A。 为啥是这样的。我在做这题之前好像就没搞太明白。
对于A+2<=B,
(A+1)(B-1) = AB+B-A-1>AB
所以对于任意选择的两个A,B都死通过调整得到A=C/2,B=C-A
推广一下,现在是对于多个数,A1,A2,A3,...,Ak
且A1+A2+A3+...+Ak=n
使得A1*A2*A3*...*Ak最大。 我们发现完全可以当成若干个C=A+B问题来解。
把大的调小,把小的调大。最后得到的一定是一段连续数字,或者两段连续数字中间只间隔1个数。
如:234567
234678
然后这题就是一个10几行代码的模拟了。
// // main.cpp // bc76 // // Created by 陈加寿 on 16/3/19. // Copyright © 2016年 chenhuan001. All rights reserved. // #include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> using namespace std; #define MOD 1000000007 long long save[100100]; int main(int argc, const char * argv[]) { int T; cin>>T; while(T--) { long long n,k; cin>>n>>k; if(k*(k+1)/2>n) { printf("-1\n"); continue; } long long x = (n - k*(k-1)/2)/k; for(int i=1;i<=k;i++) save[i] = x+i-1; long long last = (n - k*(k-1)/2)%k; for(int i=0;i<last;i++) save[k-i]++; long long ans=1; for(int i=1;i<=k;i++) ans = (ans*save[i])%MOD; cout<<ans<<endl; } return 0; }
以上是关于hdu5646(数学)的主要内容,如果未能解决你的问题,请参考以下文章
hdu-5646 DZY Loves Partition(贪心)