zoukankan      html  css  js  c++  java
  • hdu 5646 DZY Loves Partition 二分+数学分析+递推

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5646

    题意:将n分成k个正整数之和,要求k个数全部相同;并且这k个数的乘积最大为多少?结果mod 1e^9+7;

    思路:由于是mod,不能通过模拟进行比较来判断是否为最优解;那么我们就必须直接计算出这个最优解的序列;

    由于当a <= b-2时(相等时表示中间空一位),a*b < (a+1)*(b-1);所以最优解序列要不就是一串连续的序列,要不就是中间空一位,分成两段连续的序列;

    因为如果存在空格超过1个的两个数,就可以通过加1减1,移到相邻或者只空一个位;

    注意:到底空的是哪一位,与平均值并不相关;这需要看n与确定的左边界之后的k个数的和相差的值;(用二分确定左边界,使得sum[a,...a+k) <= n < sum[a...a+k]);

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    #include<stdlib.h>
    #include<time.h>
    #include<stack>
    #include<set>
    #include<map>
    #include<queue>
    using namespace std;
    #define rep0(i,l,r) for(int i = (l);i < (r);i++)
    #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
    #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
    #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
    #define MS0(a) memset(a,0,sizeof(a))
    #define MS1(a) memset(a,-1,sizeof(a))
    #define MSi(a) memset(a,0x3f,sizeof(a))
    #define inf 0x3f3f3f3f
    #define lson l, m, rt << 1
    #define rson m+1, r, rt << 1|1
    typedef pair<int,int> PII;
    #define A first
    #define B second
    #define MK make_pair
    typedef __int64 ll;
    template<typename T>
    void read1(T &m)
    {
        T x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        m = x*f;
    }
    template<typename T>
    void read2(T &a,T &b){read1(a);read1(b);}
    template<typename T>
    void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
    template<typename T>
    void out(T a)
    {
        if(a>9) out(a/10);
        putchar(a%10+'0');
    }
    
    const int mod = 1e9+7;
    int add(ll a, ll b) { return (a+b)%mod; }
    int sub(ll a, ll b) { return ((a-b)%mod + mod)%mod; }
    int mult(ll a, ll b) { return ((a * b))%mod; }
    ll n,k;
    int s[55];
    int main()
    {
        int T;
        read1(T);
        while(T--){
            read2(n,k);
            if(n < k*(k+1)/2){// 
                puts("-1");
                continue;
            }
            int tmp = n/k,a,l = 1,r = tmp;
            while(l <= r){
                int mid = l+r>>1;
                if((mid+mid+k-1)*k/2 <= n) a = mid,l = mid+1;
                else r = mid - 1;
            }
            int sum = (a+a+k-1)*k/2;// a即为确定的左边界
            ll ans = 1;
            if(sum == n){
                rep0(i,0,k) ans= mult(ans,a+i);
            }
            else{
                int t = n - sum;
                int cnt = k-t;
                rep0(i,0,cnt) ans = mult(ans,a+i);
                a++;//中间空一位
                while(cnt < k)
                    ans = mult(ans,a+cnt),cnt++;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    2020蓝桥杯模拟赛(一)
    自己整理的瀑布流+滚动加载图片的例子
    .NET如何发送格式化的文本内容
    Bootstrap学习笔记(3)--表格表单图片
    BootStap学习笔记(2)
    BootStap学习笔记(1)
    Oracle性能优化
    Maven+spring+springMVC+mybatis+Junit+Log4j配置个人总结
    C#指针和寻址运算
    Linq to XML
  • 原文地址:https://www.cnblogs.com/hxer/p/5313093.html
Copyright © 2011-2022 走看看