第三届中国计量大学ACM程序设计竞赛个人赛 C
Posted John_Ran
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第三届中国计量大学ACM程序设计竞赛个人赛 C相关的知识,希望对你有一定的参考价值。
题意:给你一个整数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