题解 P1031 [NOIP2002 提高组] 均分纸牌
link
贪心
题中描述
每一堆牌只能移动若干张牌到相邻的牌堆上
确定了局部最优解必定能推导出全局最优解。
易知均分完后,每堆牌的数量都为纸牌总数的平均数
所以我们可以预处理每堆牌跟
for (int i = 1; i <= n; ++i) sum += a[i];
int arg = sum / n;
for (int i = 1; i <= n; ++i) a[i] -= arg;
显然可以分三种情况:
- 当
时,此时这堆牌不需要移动 - 当
时,这堆牌需要从其他堆拿过来 - 当
时,这堆牌需要全部给其他牌
显然我们可以保证
写出代码
for (int i = 1; i <= n; ++i) {
if (a[i] == 0) continue; // 不需要移动
else if (a[i] > 0) { // 大于0
a[i + 1] += a[i]; // 给后面的人
ans ++; // 次数加1
}else {
a[i + 1] -= (-a[i]); // 从后面补到0
ans ++; // 次数加1
}
}
由于
于是
可以简化代码为:
for (int i = 1; i <= n; ++i) {
if (a[i] == 0) continue;
a[i + 1] += a[i];
ans ++;
}
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int n;
int a[N];
int sum = 0, ans = 0;
int main() {
ios::sync_with_stdio(false); cin.tie(0), cout.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i) cin >> a[i], sum += a[i];
int arg = sum / n;
for (int i = 1; i <= n; ++i) a[i] -= arg;
for (int i = 1; i <= n; ++i) {
if (!a[i]) continue;
a[i + 1] += a[i];
ans ++;
}
cout << ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效