洛谷P17224 搬家の题解 求赞求关注
2026-08-24 18:00:03
发布于:吉林
蒟蒻第一次写绿题题解(能写出来就是个奇迹了,版面设计上不要有太大要求,如有错误请大佬们指出,只要还没AFO呢就一定会尽快改正),走过路过还望大佬们点个关注留个赞(第一次用acgo,简直弱爆了awa)
P17224 [Math×Girl²] 搬家
题目描述
小魔女 A 和小魔女 S 有一个容量为 的箱子和 个物品。
物品按 到 编号,第 个物品的价值为 。
小魔女 A 可以决定每个物品的大小:令其为 或 。
小魔女 S 使用一个打包机,该打包机的装填策略如下:
- 优先装大小为 的物品:在大小为 的物品中,按编号从小到大依次尝试装入,直到箱子装满或所有大小为 的物品都被装入。
- 再装大小为 的物品:若还有剩余容量,在大小为 的物品中,按编号从小到大依次尝试装入,直到箱子装满或所有大小为 的物品都被装入。
小魔女 S 希望装入物品的总价值最大。如果打包机的结果不是最优解,她会手动调整为最优解。
她不知道小魔女 A 要怎么设定物品大小,所以她想知道有多少种给物品分配大小的方案,使她无需手动调整?
答案对 取模。
输入格式
一行两个正整数 。
输出格式
一行一个整数,表示方案数对 取模后的结果。
输入输出样例 #1
输入 #1
2 2
输出 #1
3
输入输出样例 #2
输入 #2
114 514
输出 #2
304170860
输入输出样例 #3
输入 #3
1919 810
输出 #3
310652647
说明/提示
样例解释
对样例 #1:有 种分配方案。
| 物品大小 | 打包机装入的物品 | 最优方案 |
|---|---|---|
共有 种方案符合要求。
数据范围与约定
本题开启捆绑测试。
| 子任务 | 分值 | 特殊性质 | |
|---|---|---|---|
| - | |||
对于 的数据,。
数学原理
根据第 i 个物品的价值为 ,可知任意一个物品价值大于其后面所有物品价值之和。
N=4时
| i | 1 | 2 | 3 | 4 |
|---|---|---|---|---|
| 对应数值 | 27 | 9 | 3 | 1 |
贪心策略:尽量拿编号小的物品,直到装满容量 𝑀。
分情况讨论
情况 1:𝑀 ≥ 𝟐𝑵
这说明箱子总容量足够放下全部物品(所有物品就算全是 2,也能全部放下)
无论打包机怎么分配大小,也全能装进去,即等于最优解。
总方案数:
情况 2:𝑀 < 𝟐𝑵
此时箱子不能放下所有的物品。
设 𝑘 为大小为 1 的物品总个数
情况 2.1:𝑘 ≥ 𝑀
大小为 1 的物品数量超过箱子容量,打包机出来后直接装入前 𝑀 个大小为 1 的物品。
后面的 𝑁 − 𝑀 个物品任意打包成大小 1 或大小 2。
则 打包结果 = 最优解
当大小为 1 的物品足够多时(𝑘 ≥ 𝑀),打包机只选大小为 1 的物品,不选择任何大小为 2 的品。
必须保证在装满之前,绝不会遇到任何一个大小为 2 的物品。
前 𝑀 − 1 个物品大小必须全为 1。
前 𝑀 − 1 个位置固定后,还剩下 𝑁 − 𝑀 + 1 个位置。这里必须至少有一个大小为 1,不能全为 2。
总方案数:
情况 2.2:𝑘 < 𝑀
此时大小为 1 的物品只有 𝑘 个,打包机会先把这 𝑘 个 1 全部装入,剩余容量为:
还能装大小为 2 的物品,最多能装:
打包机选择的是:所有编号最小的 𝑡 个大小为 2 的物品。剩下未被选中的大小为 2 的物品 有 𝑁 − 𝑘 − 𝑡
个。
核心判定条件:
在遇到第一个未被选中的 2 时,箱子必须已经装满(或只剩下 1 个容量,装不下它)。
情况 2.2.1:𝑅 为奇数
打包机装完 k 个 1 和 t 个 2 后,剩余容量为 1,再也装不下任何 2。
此时,只要在遇到 2𝑡+1 之前,前 𝑘 + 𝑡 个物品恰好包含 𝑘 个 1 和 ,那么最
优解扫描到这 𝑘 + 𝑡 个物品时,箱子正好装满(因为总大小为 𝑘 + 2𝑡 = 𝑀 − 1,,离满还差
1),遇到后面的 2 时只剩 1 容量,装不下。
这 𝑘 + 𝑡 个物品的排列中,只需要决定哪些位置放 1(其余放那 t 个特定的 2),
方案数为:
情况 2.2.2:𝑅 为偶数
打包机装完 k 个 1 和 t 个 2 后,箱子刚好装满(容量为 0)。
有效情况分两种(避免重复计数):
1. 基础情况:
前 𝑘 + 𝑡 个物品包含全部 k 个 1 和 。
最优解扫完这 𝑘 + 𝑡 个物品后容量为 0。
基础方案数为:
2. 额外情况
如果前 𝑘 + 𝑡 − 1 个物品只包含 𝑘 − 1 个 1 和 ,还剩下 1 个 1 没有出现。
此时,最优解扫完这 𝑘 + 𝑡 − 1 个物品后,剩余容量为 1,(因为总大小为 (𝑘 − 1) + 2𝑡 = 𝑀 − 1)。
它遇到后面的 2𝑡+1 时,因为容量只有 1,装不下它,只能继续往后扫描,直到遇到那最后
一个 1,把它装进去,箱子才正好装满。
为了保证不重复基础情况,最后一个 1 必须出现在第 𝑘 + 𝑡 个位置之后:
前 𝑘 + 𝑡 − 1 个位置中,选 𝑘 − 1 个放放 1,其余放 :有 种;
剩下的那一个 1,可以放在位置 𝑘 + 𝑡 + 1 到 𝑁 之之间的 任意位置 ,只要它后面全是未被选中的 2。
额外方案数为:
两部分加起来(基础与额外):
参考代码:
#include <iostream>
#include <vector>
using namespace std;
typedef long long LL;
const int MOD = 998244353;
LL qpow(LL a, LL b)
{
LL r = 1;
while(b)
{
if(b & 1) r = r * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return r;
}
LL C(LL n, LL m, const vector<int> &fact, const vector<int> &invFact)
{
if(m < 0 || n < 0 || m > n) return 0;
return 1LL * fact[n] * invFact[m] % MOD * invFact[n - m] % MOD;
}
int main()
{
LL n, m; cin >> n >> m;
LL ans = 0;
if(m >= 2 * n)
{
ans = qpow(2, n);
}
else // 2 * n - m < 0
{
int N = max(n, (n + m) / 2 + 3);
vector<int> fact(N + 1), invFact(N + 1);
fact[0] = 1;
for(int i = 1; i <= N; i++)
fact[i] = 1LL * fact[i - 1] * i % MOD;
invFact[N] = (int)qpow(fact[N], MOD -2);
for(int i = N; i >= 1; i--)
invFact[i - 1] = (int)(1LL * invFact[i] * i % MOD);
int kMax = min(n, m - 1);
int L = 2 * n - m;
if(m <= n)
ans = (qpow(2, n - m + 1) - 1 + MOD) % MOD;
for(int k = 0; k <= kMax; k++)
{
if(k >= L)
ans = (ans + C(n, k, fact, invFact)) % MOD;
else
{
int d = m - k;
int t = d / 2;
int val = 0;
if(d & 1) val = C(k + t, k, fact, invFact);
else
{
val = C(k + t, k, fact, invFact);
if(k > 0)
{
int add = 1LL * C(k + t - 1, k - 1, fact, invFact) * (n - k - t) % MOD;
val += add;
if(val >= MOD) val -= MOD;
}
}
ans += val;
if(ans >= MOD) ans -= MOD;
}
}
}
cout << ans;
return 0;
}
全部评论 10
求赞求关注!求赞求关注!求赞求关注!
23小时前 来自 吉林
1你可以在名字后面加一个(关必回)
21小时前 来自 吉林
0嗯嗯qwq
21小时前 来自 吉林
0那你怎么不加。
17小时前 来自 广东
0
拜谢 Math×Girl² 大手子/bx /bx /bx
17小时前 来自 广东
0@yxdl1,既然能写出来这个题解,那争论的意义在哪里呢
22小时前 来自 吉林
0没看懂,所以我连怀疑的资格都没有吗
22小时前 来自 浙江
0我可没有笃定你就是 AI
22小时前 来自 浙江
0不是的,我想说的是您的目的是什么呢,写了半天题解,我真的好累,下午再说吧
22小时前 来自 吉林
0
重申,我真的不想对线
22小时前 来自 吉林
0这里我也没看懂,0 个人想对线,不要过度解读
22小时前 来自 浙江
0
22小时前 来自 吉林
0我想看你的洛谷账号
22小时前 来自 浙江
0您想干什么
22小时前 来自 吉林
0我是不怎么上谷的
22小时前 来自 吉林
0
额,每个人的代码习惯都不一样,您可以借鉴一下这个,我没有一点想对线的意思,vector有很多好处,您的意思我明白,AI处处都用vector,但您如果看到我另外一部分蓝题提交记录就知道了,绿上的题我的码风都很像AI,谢谢
22小时前 来自 吉林
0怎么 ACGO 全都是 aso 实力的大佬,跪了
17小时前 来自 广东
0aso 还有后续吗 /yiw
15小时前 来自 浙江
0
不要误会啊qwq
23小时前 来自 吉林
0不太像人写的,为什么驼峰加一堆 vector
23小时前 来自 浙江
0
额,不是AI
23小时前 来自 吉林
0疑似人工生成,并非语言大模型
23小时前 来自 吉林
0是 AI 吗
23小时前 来自 浙江
0


























有帮助,赞一个