NOIP模拟day1-T1(完全背包)
题目
Maxtir 最近买了一个背包。
Maxtir 有一个容量为 m 的背包。Sao 有 n 种物品,第 i 种物品的体
积为 ai ,价值为 b i 。Sao 的每种物品都有无限多件,Maxtir 可以任取。
在不超过背包容量的前提下,Maxtir 要求所能获得的最大价值。
输入输出
输入格式
第1行输入两个正整数 n , m 。
第 2 至 n + 1行,每行输入两个正整数 ai , b i 。
输出格式
一个整数,表示 Maxtir 所能获得的最大价值。
输入样例#1
2 15
3 2
5 3
输出样例#1
10
输入样例#2
3 70
71 100
69 1
1 2
140
输入/输出样例#3
见下发文件 backpack3.in/backpack3.out
数据范围
对于 20% 的数据, n , m ≤ 103 。
对于 40% 的数据, n , m ≤ 10 4 , ai , b i ≤ 10 。
对于 60% 的数据, n , m ≤ 105 。
对于 100% 的数据, n ≤ 10 6 , m ≤ 10 16 , ai , b i ≤ 100 。
分析
本人40pts的方法就不说了,放下正确分析:
按照NOIP的惯例,此题是一道送分题。
对于 60% 的数据,我们可以发现其实 n不大于100 ,若两种物品 ai 相同,
则 bi 较小的应该被舍弃,复杂度 O(am) 。
对于100 % 的数据,我们先证明一个引理:
引理:给定任意 n 个整数,它们之中存在若干个整数的和为 n 的
倍数。
证明:设 n 个整数为 a 1 , a 2 , a3 ,……, a n , \(Sn=\sum_{i=1}^{n}ai\)。
对于 S0 , S1 , S 2 , S 3 ,…… , Sn 这 n+1 个数,至少有两个数模 n 相同,则
这两个数的差为 n 的倍数,证毕。
回到题目,设第 s 种物品为性价比最高的物品之中 ai 最小的物
品。设最优情况下有 x 件非第 s 种物品,则我们可以证明:
定理:存在一种最优情况使得 x < as 。
证明:若 x >= as ,则存在若干件物品的 ai 和为 as 的倍数,将这些物
品用第 s 种物品替换一定不劣。
于是这 x 件非第 s 种物品的 ai 和最大为 100a s 。于是我们选择
(n/as)-100 件第 s 种物品,剩下的空间做完全背包,复杂度 O(a^3)。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 105;
const int N = 2e4 + 50;
ll m, ans, cnt, f[N];
int n, p[M][M];
struct Data {
int x, y;
Data(int _x = 0, int _y = 0): x(_x), y(_y) {}
bool operator < (const Data &t) const {
int flag = x * t.y - y * t.x;
if (flag == 0) return x < t.x;
return flag < 0;
}
} a[M];
int main() {
freopen("backpack.in", "r", stdin);
freopen("backpack.out", "w", stdout);
scanf("%d%I64d", &n, &m);
for (int x, y; n--; ) {
scanf("%d%d", &x, &y);
p[x][y] = 1;
}
n = 0;
for (int x = 1; x <= 100; x++) {
for (int y = 100; y >= 1; y--) {
if (p[x][y]) {
a[++n] = Data(x, y);
break;
}
}
}
for (int i = 2; i <= n; i++)
if (a[i] < a[1]) swap(a[i], a[1]);
cnt = m / a[1].x - 100;
ans = cnt * a[1].y;
m -= cnt * a[1].x;
for (int i = 1; i <= n; i++)
for (int j = a[i].x; j <= m; j++)
f[j] = max(f[j], f[j - a[i].x] + a[i].y);
printf("%I64d\n", ans + f[m]);
return 0;
}
NOIP模拟day1-T1(完全背包)的更多相关文章
- HGOI20180817 (NOIP模拟Day1 task)
HGOI自测 初测:150=80+20+50 rank1~rank3(并列3个rank1,所以我是rank3 qwq) 今日分突然想简约 CF359A Table https://www.luogu. ...
- 洛谷P1328==codevs3716 生活大爆炸版石头剪刀布[NOIP 2014 day1 T1]
P1328 生活大爆炸版石头剪刀布 1.8K通过 2.6K提交 题目提供者2014白永忻 标签模拟NOIp提高组2014 难度普及- 提交该题 讨论 题解 记录 最新讨论 Who can help m ...
- 20161007 NOIP 模拟赛 T1 解题报告
排序 3.1 题意描述 众所周知,熟练掌握至少一种排序算法是参加NOIP的必备技能.常见的排序算法有冒泡 排序.归并排序.快速排序.奇偶排序.猴子排序.梳排序.鸡尾酒排序.臭皮匠排序等. 在这里,介绍 ...
- noip 2016 day1 T1玩具谜题
题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: 这时singer告诉 ...
- 【2019.7.20 NOIP模拟赛 T1】A(A)(暴搜)
打表+暴搜 这道题目,显然是需要打表的,不过打表的方式可以有很多. 我是打了两个表,分别表示每个数字所需的火柴棒根数以及从一个数字到另一个数字,除了需要去除或加入的火柴棒外,至少需要几根火柴棒. 然后 ...
- 【2019.7.25 NOIP模拟赛 T1】变换(change)(思维+大分类讨论)
几个性质 我们通过推式子可以发现: \[B⇒AC⇒AAB⇒AAAC⇒C\] \[C⇒AB⇒AAC⇒AAAB⇒B\] 也就是说: 性质一: \(B,C\)可以相互转换. 则我们再次推式子可以发现: \[ ...
- 20161022 NOIP模拟赛 T1 解题报告
旅行者问题 [问题描述] lahub是一个旅行者的粉丝,他想成为一个真正的旅行者,所以他计划开始一段旅行.lahub想去参观n个目的地(都在一条直道上).lahub在起点开始他的旅行.第i个目的地和起 ...
- 20161023 NOIP 模拟赛 T1 解题报告
Task 1.纸盒子 (box.pas/box.c/box.cpp) [题目描述] Mcx是一个有轻度洁癖的小朋友.有一天,当他沉溺于数学卷子难以自拔的时候,恍惚间想起在自己当初学习概率的时候准备的一 ...
- 20161004 NOIP 模拟赛 T1 解题报告
第1题 小麦亩产一千八 [问题描述] “有了金坷垃,肥料一袋能顶两袋撒,小麦亩产一千八,吸收两米下的氮磷钾……”,话说HYSBZ(Hengyang School for Boys & Zy) ...
- 2014.7建兰NOIP模拟Day1 Running
突然间翻到着题,想想那时的我真是垃圾,这么简单的tarjan缩点+树上倍增都不会..还想了3h+.. 什么时候写了它吧...
随机推荐
- Traefik 2.0 tcp 路由试用
对于tcp 的路由是基于sni (需要tls)但是可以通过统配(*) 解决不试用tls的,当然也可以让Traefik 自动生成tls 证书 以下是测试http 以及mysql 的tcp 路由配置(de ...
- 工作拾记 - 关于easyui模板后台改为vue-element
图1: 数据接口,模拟实现一些基本的数据条目 图2: 获取数据,接口都在src/api中 TODO LIST: 接下来要做的呢: 1. 完善此demo,基本的CURD,现在只有getAll,需要将增加 ...
- 常用方法 Entitys转换为DataTable
效率比较屁,将近可以用 public static DataTable EntitiesToDataTable<T>(List<T> entitys) { Type t = t ...
- C++智能指针总结
本文介绍c++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三个是c++11支持,并且第一个已经被c++11弃用. 为什么要使用智能 ...
- 利用 Matplotlib 绘图
各类绘图 ## 导入包 import matplotlib as mpl import matplotlib.pyplot as plt import seaborn as sns ## 参数设置 # ...
- 简单find命令的实现
贴代码: /*实现一个简单的find命令:*//*程序思路:首先,用一个单链表将所需要的信息存储起来:其次根据所传入的参数信息,改变节点的状态(若有这个状态,证明该节点就是我们所需要的)最后将所需要的 ...
- 安全测试基础-SQL注入详解
1:什么是SQL注入 SQL注入是一种将SQL代码插入或添加到应用(用户)的输入参数中的攻击,之后再将这些参数传递给后台的SQL服务器加以解析并执行. www.xx.com/news.php?id=1 ...
- kafka(二) 高性能技术分析
参考文章: http://www.infoq.com/cn/articles/kafka-analysis-part-6 Partition提供并行处理的能力 Kafka是一个Pub-Sub的消息系统 ...
- 源码编译Redis Desktop Manager ---(转载)
精美文章转载: 版权声明:本文作者为「Kany.Wang」,本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议.转载请注明出处!原文链接:https://kany.me/20 ...
- 微信小程序 获取地理位置信息
app.json "permission":{ "scope.userLocation": { "desc": "你的位置信息将用 ...