题目传送门
一道非常简单难做的绿题。
一、思路
首先就是审题,一看到价值和重量,我第一时间就想到 01 背包问题,脑袋一热,直接交了个模版代码。
#include<bits/stdc++.h>
using namespace std;
int f[1000];
int w[1000],v[1000];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>w[i]>>v[i];
}
for(int i=1;i<=n;i++)
{
for(int j=m;j>=w[i];j--)
{
f[j]=max(f[j],f[j-w[i]]+v[i]);
}
}
cout<<f[n];
return 0;
}
然后听取 WA 声一片。
再次审题,发现
并且对于塔中的每一块砖来说,它上面所有砖的重量和不能超过它自身的价值。
咕,当场石化。
原本想要跑
N
N
N 次 01 背包,但 TLE 了,就无语。
既然如此,那么我们可以将其排个序,使小明先放一些后放一些不就完美解决了吗?
按照什么顺序来排呢?
设两砖头名称为
A
A
A,
B
B
B,重量为
w
e
i
g
h
t
weight
weight,
价值为
v
a
l
u
e
value
value。
那么可得
w e i g h t A − v a l u e B ≤ w e i g h t B − v a l u e A weight_A-value_B\leq weight_B-value_A weightA−valueB≤weightB−valueA
移项得
w e i g h t A + v a l u e A ≤ w e i g h t B + v a l u e B weight_A+value_A\leq weight_B+value_B weightA+valueA≤weightB+valueB
所以按照以上顺序排序即可。
AC CODE
#include<bits/stdc++.h>
using namespace std;
int f[100010];
struct brick//结构体
{
int weight;// 重量
int value;// 价值
}brick_[100010];//开大点,好习惯
bool cmp(brick a,brick b)
{
if(a.weight+a.value<=b.weight+b.value) return true;
return false;
}//排序
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>brick_[i].weight>>brick_[i].value;
}
int maxn=-1;//最大值
sort(brick_,brick_+n+1,cmp);
for(int i=1;i<=n;i++)
{
for(int j=brick_[i].value+brick_[i].weight;j>=brick_[i].weight;j--)
{
f[j]=max(f[j],f[j-brick_[i].weight]+brick_[i].value);
maxn=max(f[j],maxn);
}
}
cout<<maxn;
return 0;//华丽结束
}