T1:分段求平均数
本题难度中等,划分型DP问题。用 dp[i]
表示前 个数最少划分成几段,对 判断从 到 划分成一段时,平均数是否为整数,如果是整数,就更新
初始值:
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n; cin >> n; vector<int> a(n); rep(i, n) cin >> a[i]; vector<int> s(n+1); rep(i, n) s[i+1] = s[i]+a[i]; vector<int> dp(n+1); rep(i, n+1) dp[i] = i; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= i; ++j) { if ((s[i]-s[j-1])%(i-j+1) == 0) { dp[i] = min(dp[i], dp[j-1]+1); } } } cout << dp[n] << '\n'; return 0; }
T2:余数的余数
本题难度较大, 直接枚举 的所有全排列即可。
当 时, 。利用这一性质,计算余数时,如果模了一个较小数 ,那么如果后面的 比 大,这个 对最终的余数就没有影响了,所以当确定了 数组的顺序后,对最终余数有影响的,只有每次新出现的更小 。
例如 ,第 次 之后,接下来的 , 对余数都没有影响;接下来的模数是 ,比 小,所以会对余数有影响;接下来 , 比 小,所以会对余数有影响;最后的 比 大,所以对余数都没有影响。最终这个 序列中,对余数有影响的只有 这个递减序列。
于是我们可以用子集枚举,先枚举出递减序列中的 ,然后按照递减顺序依次计算余数,就可以得到所有可能的余数 的值。
代码实现时,先把 排序成递减顺序再枚举子集比较好写。
代码实现
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); ++i) using namespace std; int main() { int n, k; cin >> n >> k; vector<int> a(n); rep(i, n) cin >> a[i]; sort(a.rbegin(), a.rend()); int ans = 0; auto dfs = [&](auto f, int i, int r) -> void { if (r <= ans) return; if (i == n-1) { ans = max(ans, r%a[n-1]); return; } f(f, i+1, r); f(f, i+1, r%a[i]); }; dfs(dfs, 0, k); cout << ans << '\n'; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现