第三届中国计量大学ACM程序设计竞赛个人赛 C

Posted John_Ran

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第三届中国计量大学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;
}

以上是关于第三届中国计量大学ACM程序设计竞赛个人赛 C的主要内容,如果未能解决你的问题,请参考以下文章

2018 ACM-ICPC 中国大学生程序设计竞赛暨丝绸之路程序设计竞赛

比较好的大学生C语言竞赛编程题 或者比较有档次的竞赛都有哪些(本科、研究生可以参加的) ?

智能车竞赛技术报告 | 智能车视觉 - 中国计量大学 - 赛博-10

智能车竞赛技术报告 | 节能信标组 - 中国计量大学 - 赛博 - 8

[2012山东省第三届ACM大学生程序设计竞赛]——Mine Number

2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 B. Goldbach-米勒拉宾素数判定(大素数)