首页 > 编程语言 >第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)

第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)

时间:2023-03-18 10:31:40浏览次数:55  
标签:PII AC 杯国赛 long 蓝桥 int second first define


目录

  • ​​1.搬砖​​
  • ​​1.题目描述​​
  • ​​2.输入格式​​
  • ​​3.输出格式​​
  • ​​4.样例输入​​
  • ​​5.样例输出​​
  • ​​6.数据范围​​
  • ​​7.原题链接​​
  • ​​2.解题思路​​
  • ​​3.Ac_code​​

1.搬砖

1.题目描述

这天,小明在搬砖。

他一共有 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式 块砖, 他发现第 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_02 砖的重量为 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_c++_03, 价值为 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_04

他想知道这样堆成的塔的总价值(即塔中所有砖块的价值和)最大是多少。

2.输入格式

输入共 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_05 行, 第一行为一个正整数 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式, 表示砖块的数量。后面 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式 行, 每行两个正整数 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_蓝桥杯_08
分别表示每块砖的重量和价值。

3.输出格式

一行, 一个整数表示答案。

4.样例输入

5
4 4
1 1
5 2
5 5
4 3

5.样例输出

10

6.数据范围

第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_蓝桥杯_09

7.原题链接

​搬砖​

2.解题思路

诸如此题的模型,思路都是按照一种方式排序,使得最优解答案的选择情况,是排序后的一个子序列,然后直接进行背包 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_蓝桥杯_10

那么该如何去寻找排序的条件呢?一般的思路在于,对于砖块 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_11第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式_12,如果排序后的结果 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式_12第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_11的后面,那么对于任意 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式_12第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_11 之上的摆放情况,都一定可以将两者调换。

第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_蓝桥杯_17


如图,红色砖块为 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式_12 上所有砖块的重量,我们设为 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_19,绿色为 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_11第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式_12 之间的砖块重量,我们设为 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_c++_22

根据题意可知:第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_c++_23,​​​1​​​ 假设排序后 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式_12第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_11 的后面,那么也一定满足:第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式_26​2​

因为第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式_27​​​1​​​且第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_28一定大于 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_算法_29,显然第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_30是一定符合要求的。

然后考虑第二个式子,因为 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_输出格式_27​​​1​​​,经过变形可得 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_32​​​3​​​ 将式子​​3​​带入式子​​2​​可得:
第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_c++_33
将式子整理可得:
第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_34
由此,我们找到了排序条件,也就是说,当满足 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_34 时,任意 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_算法_36第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_37

接下来就是进行背包 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_蓝桥杯_10即可,
定义 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_c++_39为只考虑前 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_数据结构_02 个物品,且选择的重量为 第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_算法_41

第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_算法_42

题目体积最大只有​​2e4​​​,答案即为从第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_蓝桥杯_43第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_c++_44取个最大值。由于是​​​01​​背包问题,可以使用滚动数组进行优化。

时间复杂度:第十三届蓝桥杯国赛 C++ B 组 J 题——搬砖(AC)_算法_45

3.Ac_code

未优化版本:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
#define pb(s) push_back(s);
#define SZ(s) ((int)s.size());
#define ms(s,x) memset(s, x, sizeof(s))
#define all(s) s.begin(),s.end()
const int inf = 0x3f3f3f3f;
const int mod = 1000000007;
const int N = 1010;


int n;
//只考虑前 i 个砖块,且重量为 j 的最大价值
int f[N][N * 20];
PII a[N];
bool cmp(PII b, PII c) {
return b.first + b.second < c.first + c.second;
}
void solve()
{
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i].first >> a[i].second;
}
sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; ++i) {
int w = a[i].first, v = a[i].second;
for (int j = 0; j <= 20000; ++j) {
f[i][j] = f[i - 1][j];
//可选情况
if (w <= j && v >= j - w) f[i][j] = max(f[i][j], f[i - 1][j - w] + v);
}
}
int ans=0;
for(int i=0;i<=20000;++i) ans=max(ans,f[n][i]);
cout << ans << '\n';
}
int main()
{
ios_base :: sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int t = 1;
while (t--)
{
solve();
}
return 0;
}

滚动数组优化:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
#define pb(s) push_back(s);
#define SZ(s) ((int)s.size());
#define ms(s,x) memset(s, x, sizeof(s))
#define all(s) s.begin(),s.end()
const int inf = 0x3f3f3f3f;
const int mod = 1000000007;
const int N = 1010;


int n;
//只考虑前 i 个砖块,且重量为 j 的最大价值
int f[N * 20];
PII a[N];
bool cmp(PII b, PII c) {
return b.first + b.second < c.first + c.second;
}
void solve()
{
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i].first >> a[i].second;
}
sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; ++i) {
int w = a[i].first, v = a[i].second;
for (int j = 20000; j >= w; --j) {
//可选情况
if ( v >= j - w) f[j] = max(f[j], f[j - w] + v);
}
}
int ans = 0;
for (int i = 0; i <= 20000; ++i) ans = max(ans, f[i]);
cout << ans << '\n';
}
int main()
{
ios_base :: sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int t = 1;
while (t--)
{
solve();
}
return 0;
}


标签:PII,AC,杯国赛,long,蓝桥,int,second,first,define
From: https://blog.51cto.com/u_15492302/6129361

相关文章