第三届中国计量大学ACM程序设计竞赛个人赛 C
题意:给你一个整数N,定义一次操作为将这个数字切割为一个等差数列,如果有多种方案,只能选择元素最多的方式。切割之后的数据仍然能继续切割,但是每次只能选择一个元素进行切割,问最多能进行多少次操作?
题解:简单dp,首先需要考虑对于一个数字而言,切割得最多的方法的左端点和右端点,这个可以通过倒序暴力扫左端点得到(由调和级数可知复杂度是)。其次,我们需要维护一个前缀和,表示[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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~