当前位置:网站首页>2020蓝桥杯国赛B组-搬砖-(贪心排序+01背包)
2020蓝桥杯国赛B组-搬砖-(贪心排序+01背包)
2022-06-30 15:44:00 【可爱美少女】
题意:
就是给你n个砖头,每个砖头有个重量和价值,现在让你把一些砖块垒起来,对于每个砖块,他上面的所有砖块的重量不能超过他本身的价值。问你这个垒起来的砖块价值总和最大是多少。
思考:
比赛时感觉后面的也都不简单,实际上多思考思考就好了。首先想到的就是dp,但是对于每个砖块怎么保证,他上面的重量总和小于等于他的价值呢,这个该怎么维护呢。实际上在纸上画一画,思考一下可以先处理上面的砖块,再处理下面的砖块,一点一点的处理,因为你如果先处理下面的砖块,你怎么选对吧,才能保证下面的都满足。所以先考虑上面的,从上往下每个砖块都能线性处理。定义dp[i][j]是用了前i个砖块,此时重量为j的时候的最大价值。但是这样该怎么枚举砖块的顺序呢?实际上这就是要排序,以前就做过这种,比如国王的游戏。这题可以让i在上面,j在下面,我们让wi+sum<vj,wj+sum>vi,也就是让i在上面的时候j可以选,让i在下面的时候,j不可以选了。所以转化一下这个公式,可以把sum丢掉,sum是上面所有的重量。然后公式就是wi<vj,vi<wj。两个想加可以得到wi+vi<wj+vj。所以按这个排序就行。然后对于维护每个砖块上面的重量小于他的价值,其实在dp的时候加个判断条件就够了。然后其实就是01背包,加了一个贪心排序,和多了一个判断条件。可以优化为1维的。
代码:
二维版本:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 1e5+10,M = 2010;
int T,n,m,k;
PII va[N];
int dp[1005][20005];
bool cmp(PII A,PII B)
{
return A.fi+A.se<B.fi+B.se;
}
signed main()
{
IOS;
cin>>n;
for(int i=1;i<=n;i++) cin>>va[i].fi>>va[i].se;
sort(va+1,va+1+n,cmp);
m = n*20; //重量最多是这些
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
dp[i][j] = max(dp[i][j],dp[i-1][j]); //如果这个砖块不选
if(va[i].se>=j-va[i].fi&&j>=va[i].fi) dp[i][j] = max(dp[i][j],dp[i-1][j-va[i].fi]+va[i].se); //如果选,要保证价值大于上面的总重量。
}
}
int maxn = 0;
for(int j=0;j<=m;j++) maxn = max(maxn,dp[n][j]);
cout<<maxn;
return 0;
}
一维版本:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 1e5+10,M = 2010;
int T,n,m,k;
PII va[N];
int dp[20005];
bool cmp(PII A,PII B)
{
return A.fi+A.se<B.fi+B.se;
}
signed main()
{
IOS;
cin>>n;
for(int i=1;i<=n;i++) cin>>va[i].fi>>va[i].se;
sort(va+1,va+1+n,cmp);
m = n*20;
for(int i=1;i<=n;i++)
{
for(int j=m;j>=0;j--)
{
if(va[i].se>=j-va[i].fi&&j>=va[i].fi)
dp[j] = max(dp[j],dp[j-va[i].fi]+va[i].se);
}
}
int maxn = 0;
for(int j=0;j<=m;j++) maxn = max(maxn,dp[j]);
cout<<maxn;
return 0;
}
总结:
多多思考呀,其实都不难,这就是以前在upc做过的原题可以说。
边栏推荐
猜你喜欢

Generating verification code with sring

快照和备份
![[algorithm] after summarizing the four linked lists, I brushed two interview questions](/img/04/1843e01cc91cdf10ae3d3d6a4f1e05.png)
[algorithm] after summarizing the four linked lists, I brushed two interview questions

服务端测试工程师面试经验

备战数学建模34-BP神经网络预测2

婴儿认知学习所带来的启发,也许是下一代无监督机器学习的关键

Simulation of two-color ball system to judge the winning situation
![Warning: [antd: Menu] `children` will be removed in next major version. Please use `items` instead.](/img/c1/99ad29789a669c4498fb93ce1fb009.png)
Warning: [antd: Menu] `children` will be removed in next major version. Please use `items` instead.

《网络是怎么样连接的》读书笔记 - 汇总篇

Cesium-1.72 learning (deploy offline resources)
随机推荐
备战数学建模35-时间序列预测模型
MC Instruction Decoder
RTP 发送PS流零拷贝方案
[附下载]渗透测试神器Nessus安装及使用
实时渲染和预渲染有什么区别
中国传奇教授李泽湘,正在批量制造独角兽
What role does "low code" play in enterprise digital transformation?
几百行代码实现一个 JSON 解析器
Go-Micro安装
猎头5万挖我去VC
Reptile (1) - Introduction to basic reptile theory
Swagger's asp Net core web API help page
Simulation of two-color ball system to judge the winning situation
Interesting research on mouse pointer interaction
互联网研发效能之去哪儿网(Qunar)核心领域DevOps落地实践
牛客网:最小花费爬楼梯
Policy Center-User Data
服务端测试工程师面试经验
《网络是怎么样连接的》读书笔记 - 汇总篇
【牛客网刷题系列 之 Verilog快速入门】~ 位拆分与运算