7-20集训总结
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:; }