720集训总结

T2 背包

题面

给$n$个物品,每个物品有两个值$a_i,b_i$,其中$a_i$表示体积。现在有一个体积为$v$的背包,每次选入一个物品,如果放得下则体积增大$b_i$。问能否全部选入。

题解

这题明显就是推式子。先把$b_i \geq a_i$的能选就选。可以推出来按$b_i$从大到小选入一定最优,直接贪心即可。

总结

考试的时候用了三目运算符,结果没打括号,被自动把逗号前面一段括起来算了。然后把$a,b$写反了。

代码:

#include <cstdio>
#include <algorithm>
#define ll long long
#define N 100005
void rd(int &x)
{
	int f=1; x=0; char s=getchar();
	while(s<'0'||s>'9') { if(s=='-')f=-1; s=getchar(); }
	while(s>='0'&&s<='9') { x=x*10+s-'0'; s=getchar(); }
	x*=f;
}
int T, n, a[N][2], tp, b[N][2], id[N], top;
ll v;
bool cmpa(int x, int y) { return a[x][0]<a[y][0]; }
bool cmpb(int x, int y) { return b[x][1]>b[y][1]; }
int main()
{
	rd(T);
	while(T--)
	{
		tp=top=0;
		int tmp=0;
		rd(n), rd(tmp);
		v=tmp;
		for(int i=1, x, y; i<=n; ++i)
		{
			rd(x), rd(y);
			x<=y?a[++tp][0]=x, a[tp][1]=y:(b[++top][0]=x, b[top][1]=y);
		}
		for(int i=1; i<=tp; ++i) id[i]=i;
		std::sort(id+1, id+tp+1, cmpa);
		for(int i=1; i<=tp; ++i) if(v>=a[id[i]][0]) v+=a[id[i]][1]-a[id[i]][0];
		else { puts("No"); goto out; }
		for(int i=1; i<=top; ++i) id[i]=i;
		std::sort(id+1, id+top+1, cmpb);
		for(int i=1; i<=top; ++i) if(v>=b[id[i]][0]) v+=b[id[i]][1]-b[id[i]][0];
		else { puts("No"); goto out; }
		puts("Yes");
		out:;
	}

  

原文地址:https://www.cnblogs.com/ynycoding/p/13375588.html