P5322 BJOI2019 排兵布阵
本题主要考察对模型的转化能力。
首先要察觉两条性质:
- 对于一个城堡,想打败一个玩家的同时用最少的士兵,肯定是正好派出这个玩家在这个城堡派出的士兵数量的二倍加一名士兵。
- 在一个城堡上,打败了一个在这个城堡派出士兵数量为
的玩家,就可以顺便打败所有在这个城堡派出士兵数量 的玩家。
这两条性质可以推出一条关键结论:在总共
问题可以转化成:
总共
第
这样以来,我们可以将在第
每组物品只能选择一个,因为选择第
到这里就变成分组背包问题了。时间复杂度
/*
* @Author: crab-in-the-northeast
* @Date: 2023-04-20 11:39:30
* @Last Modified by: crab-in-the-northeast
* @Last Modified time: 2023-04-20 12:35:49
*/
#include <bits/stdc++.h>
inline int read() {
int x = 0;
bool f = true;
char ch = getchar();
for (; !isdigit(ch); ch = getchar())
if (ch == '-')
f = false;
for (; isdigit(ch); ch = getchar())
x = (x << 1) + (x << 3) + ch - '0';
return f ? x : (~(x - 1));
}
inline bool gmx(int &a, int b) {
return b > a ? a = b, true : false;
}
const int maxs = 105;
const int maxn = 105;
const int maxm = 20005;
int f[maxm];
std :: vector <int> a[maxn];
int main() {
int s = read(), n = read(), m = read();
for (int i = 1; i <= n; ++i)
a[i].push_back(0);
for (int i = 1; i <= s; ++i)
for (int j = 1; j <= n; ++j)
a[j].push_back(read());
for (int i = 1; i <= n; ++i)
std :: sort(a[i].begin(), a[i].end());
for (int i = 1; i <= n; ++i)
for (int v = m; ~v; --v)
for (int k = 1; k <= s && 2 * a[i][k] + 1 <= v; ++k)
gmx(f[v], f[v - 2 * a[i][k] - 1] + i * k);
printf("%d\n", f[m]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】