zoukankan      html  css  js  c++  java
  • 第三届中国计量大学ACM程序设计竞赛个人赛 C

    Pinch Pinch Pinch

    传送门

    题意:给你一个整数N,定义一次操作为将这个数字切割为一个等差数列,如果有多种方案,只能选择元素最多的方式。切割之后的数据仍然能继续切割,但是每次只能选择一个元素进行切割,问最多能进行多少次操作?

    题解:简单dp,首先需要考虑对于一个数字而言,切割得最多的方法的左端点和右端点,这个可以通过倒序暴力扫左端点得到(由调和级数可知复杂度是(O(nlog(n))))。其次,我们需要维护一个前缀和,表示[1,n]中,每一个数的可以拆分的次数,然后转移就可以了,具体见代码。

    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int N = 1000005;
    
    const int MOD = 1000000007;
    
    template<typename T>
    void chmin(T& a, T b){if(a>b)a=b;}
    
    template<typename T>
    void chmax(T& a, T b){if(b>a)a=b;}
    
    int L[N],R[N],sum[N],dp[N];
    
    int main(){
        int t=read();
    
        int n=1000000;
        for(int i=n;i>=1;--i){
            int tot=i;
            for(int j=i+1;j<=n;++j){
                tot+=j;
                if(tot>n)break;
                L[tot]=i,R[tot]=j;
            }
        }
    
        for(int i=1;i<=n;++i){
            if(L[i])chmax(dp[i],sum[R[i]]-sum[L[i]-1]+1);
            sum[i]=sum[i-1]+dp[i];
        }
    
        while(t--){
            int x=read();
            cout<<dp[x]<<endl;
        }
    
    
    
        return 0;
    }
    
    
  • 相关阅读:
    需求的有序化和方案的系统化
    产品 增长 口碑传播
    私域流量的价值 大悦城微信营销:14万微信会员哪来的
    产品创新阶段关口细则
    业务关键数据指标
    TOB 增长
    医美品零售门店分析
    数据赋能饮品轻食
    [已读]你不知道的JavaScript(上卷)
    [已读]移动web手册
  • 原文地址:https://www.cnblogs.com/JohnRan/p/13043681.html
Copyright © 2011-2022 走看看