【CF3B Lorry】题解

题目链接

题目

A group of tourists is going to kayak and catamaran tour. A rented lorry has arrived to the boat depot to take kayaks and catamarans to the point of departure. It's known that all kayaks are of the same size (and each of them occupies the space of 1 cubic metre), and all catamarans are of the same size, but two times bigger than kayaks (and occupy the space of 2 cubic metres).

Each waterborne vehicle has a particular carrying capacity, and it should be noted that waterborne vehicles that look the same can have different carrying capacities. Knowing the truck body volume and the list of waterborne vehicles in the boat depot (for each one its type and carrying capacity are known), find out such set of vehicles that can be taken in the lorry, and that has the maximum total carrying capacity. The truck body volume of the lorry can be used effectively, that is to say you can always put into the lorry a waterborne vehicle that occupies the space not exceeding the free space left in the truck body.

有一辆载重量为 v 的货车, 准备运送两种物品。 物品 A 的重量为 1, 物体 B 的重量为 2, 每个物品都有一个价值。 求货车可以运送的物品的最大价值。

思路

由于每个物品重量只有1或2,我们可以先按性价比排序。最后如果还有1个重量剩下,要么是从剩下的选一个A物品,要么是退回一个A物品拿个B物品。

考虑清楚就行。

总结

这道题表面上是背包,但由于重量很小,我们只需要考虑清楚,贪心即可,并不难。这种题要注意的是剩下一个重量可能可以退A买B,以后类似的题目可以注意。

Code

// Problem: CF3B Lorry
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF3B
// Memory Limit: 62 MB
// Time Limit: 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 100010
struct node
{
	int v, p, id; 
}a[N]; 
int n, m, i, j, k, ans; 

bool cmp(node x, node y)
{
	return x.p*(2/x.v)>y.p*(2/y.v); 
}

int q1(int m)
{
	int ans=0; 
	for(i=1; i<=n; ++i)
		if(m>=a[i].v)
			ans+=a[i].p, m-=a[i].v; 
	return ans; 
}

int q2(int m)
{
	int ans=0; 
	for(i=1; i<=n&&m>=a[i].v; ++i)
	{
		m-=a[i].v; ans+=a[i].p; 
		if(a[i].v==1) k=a[i].p; 
	}
	// printf("%lld %lld %lld\n", ans, a[i].p, k); 
	if(m&&i<=n&&k!=-0x7ffffffff) ans=ans-k+a[i].p; 
	// printf("%lld")
	return ans; 
}

void q1x(int m)
{
	// printf("-"); 
	for(i=1; i<=n; ++i)
		if(m>=a[i].v)
			m-=a[i].v, printf("%lld\n", a[i].id); 
}

void q2x(int m)
{
	for(i=1; i<=n&&m>=a[i].v; ++i)
	{
		if(a[i].p==k&&a[i].v==1) {k=-0x7ffffffff; continue; }
		m-=a[i].v; printf("%lld\n", a[i].id); 
	}
}

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); m=read(); k=-0x7ffffffff; 
	for(i=1; i<=n; ++i)
		a[i].v=read(), a[i].p=read(), a[i].id=i; 
	sort(a+1, a+n+1, cmp); 
	// for(i=1; i<=n; ++i) printf("%lld %lld\n", a[i].v, a[i].p); 
	printf("%lld\n", max(q1(m), q2(m))); 
	// printf("%lld\n", k); 
	if(q1(m)>=q2(m)) q1x(m); 
	else q2x(m); 
	return 0; 
}
posted @ 2021-12-22 18:32  zhangtingxi  阅读(79)  评论(0编辑  收藏  举报