Zirnc's Blog

Recent content on Zirnc's Blog

马上订阅 Zirnc's Blog RSS 更新: https://blog.chungzh.cn/index.xml

Luogu-P1776 宝物筛选

2022年8月12日 08:00

Luogu-P1776 宝物筛选

题意

终于,破解了千年的难题。小 FF 找到了王室的宝物室,里面堆满了无数价值连城的宝物。

这下小 FF 可发财了,嘎嘎。但是这里的宝物实在是太多了,小 FF 的采集车似乎装不下那么多宝物。看来小 FF 只能含泪舍弃其中的一部分宝物了。

小 FF 对洞穴里的宝物进行了整理,他发现每样宝物都有一件或者多件。他粗略估算了下每样宝物的价值,之后开始了宝物筛选工作:小 FF 有一个最大载重为 $W$ 的采集车,洞穴里总共有 $n$ 种宝物,每种宝物的价值为 $v_i$,重量为 $w_i$,每种宝物有 $m_i$ 件。小 FF 希望在采集车不超载的前提下,选择一些宝物装进采集车,使得它们的价值和最大。

对于 $100%$ 的数据,$n\leq \sum m_i \leq 10^5$,$0\le W\leq 4\times 10^4$,$1\leq n\le 100$。

解法 1:二进制优化

每一个数都可以表示成 $2$ 的幂的和(因为每一个数都可以用二进制表示)。

时间复杂度:$O(nW\sum \log m_i)$

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <bits/stdc++.h>
using namespace std;
int dp[40005];
int main()
{
 int n, W;
 scanf("%d%d", &n, &W);
 for (int i = 0; i < n; i++) {
 int t, c, p;
 scanf("%d%d%d", &c, &t, &p);
 int tmp = 1;
 while (p >= tmp) {
 p -= tmp;
 for (int j = W; j >= t*tmp; j--)
 dp[j] = max(dp[j], dp[j-t*tmp]+c*tmp);
 tmp *= 2;
 }
 if...

剩余内容已隐藏

查看完整文章以阅读更多