1.逃出金字塔(escape)
#include<bits/stdc++.h>
using namespace std;
inline long long read(){
long long num=0;int z=1;char c=getchar();
if(c=='-') z=-1;
while((c<'0'||c>'9')&&c!='-') c=getchar();
if(c=='-') z=-1,c=getchar();
while(c>='0'&&c<='9') num=(num<<1)+(num<<3)+(c^48),c=getchar();
return z*num;
}
priority_queue<int>ll;
struct on{
long long t,d;
}a[50005];
int n,k,ans;
long long ti;
bool cmp(on x,on y)
{
return x.d<y.d;
}
int main(){
n=read();k=read();
for(int i=1;i<=n;i++)
{
a[i].t=read();a[i].d=read();
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
ti+=a[i].t;
ll.push(a[i].t);
while(ti>a[i].d)
{
ti-=ll.top();
ll.pop();ans++;
}
}
if(ans>=k){
cout<<"-1"<<endl;
return 0;
}
printf("%d",ans);
return 0;
}
2880: 带走物品(lopov)
有n件物品,每件物品有质量ai和价值bi。
BSNY有m个袋子,每袋可容纳的最大质量为ci,且每袋仅能放一个物品,问最多可以带走多少价值的物品?
luooj
思路
排序后找可以范围内最大的;
#include<bits/stdc++.h>
using namespace std;
inline long long read(){
long long num=0;int z=1;char c=getchar();
if(c=='-') z=-1;
while((c<'0'||c>'9')&&c!='-') c=getchar();
if(c=='-') z=-1,c=getchar();
while(c>='0'&&c<='9') num=(num<<1)+(num<<3)+(c^48),c=getchar();
return z*num;
}
int m,n,c[300006];
struct d{
int a,b;
}s[300006];
bool cmp(d x,d y)
{
if(x.a!=y.a)return x.a<y.a;
return x.b>y.b;
}
priority_queue<int>q;
int main(){
n=read();m=read();
for(int i=1;i<=n;i++)s[i].a=read(),s[i].b=read();
sort(s+1,s+n+1,cmp);
for(int i=1;i<=m;i++)
{
c[i]=read();
}
sort(c+1,c+m+1);
int j=1;
long long ans=0;
for(int i=1;i<=m;i++)
{
while(s[j].a<=c[i]&&j<=n)//核心
{
q.push(s[j].b);//可以就插入
j++;
}
if(!q.empty())//取可以的最大值
{
ans+=q.top();
q.pop();
}
}
printf("%lld",ans);
return 0;
}
问题 E: 股票的收益(invest)
手写堆,随机修改
#include<bits/stdc++.h>
using namespace std;
inline long long read(){
long long num=0;int z=1;char c=getchar();
if(c=='-') z=-1;
while((c<'0'||c>'9')&&c!='-') c=getchar();
if(c=='-') z=-1,c=getchar();
while(c>='0'&&c<='9') num=(num<<1)+(num<<3)+(c^48),c=getchar();
return z*num;
}
int n,tot;
int a[100005],c[100005],id[100005],di[1000005];
void up(int p){
while(p>1){
if(c[p]>c[p>>1]){
swap(c[p],c[p>>1]);
swap(id[p],id[p>>1]);
di[id[p]]=p,di[id[p>>1]]=p>>1;
p>>=1;
}
else if(c[p]==c[p>>1]&&id[p]<id[p>>1]){
swap(c[p],c[p>>1]);
swap(id[p],id[p>>1]);
di[id[p]]=p,di[id[p>>1]]=p>>1;
p>>=1;
}
else break;
}
return ;
}
void insert(int val,int k){
c[++tot]=val;id[tot]=k;di[id[tot]]=tot;
up(tot);
return ;
}
void down(int p){
int q=p<<1;
while(q<=tot){
if(q<tot){
if(c[q]<c[q+1]) q++;
else if(c[q]==c[q+1]&&id[q+1]<id[q]) q++;
}
if(c[q]>c[p]){
swap(c[q],c[p]);
swap(id[q],id[p]);
di[id[q]]=q,di[id[p]]=p;
p=q,q=p<<1;
}
else if(c[q]==c[p]&&id[q]<id[p]){
swap(c[q],c[p]);
swap(id[q],id[p]);
di[id[q]]=q,di[id[p]]=p;
p=q,q=p<<1;
}
else break;
}
return ;
}
int main(){
n=read();
for(int i=1;i<=n;i++)
{
a[i]=read();insert(0,i);
}
char s[100];
while(~scanf("%s",s+1))
{
if(s[1]=='E')break;
if(s[1]=='R')
{
printf("%d ",id[1]);
if(tot>=3){
if(c[2]==c[3]){
if(id[2]<id[3]) printf("%d\n",id[2]);
else printf("%d\n",id[3]);
}
else if(c[2]<c[3]) printf("%d\n",id[3]);
else printf("%d\n",id[2]);
}
else printf("%d\n",id[2]);
}
else{
int len=strlen(s+1),ans=0;
for(int i=1;i<=len;i++) ans=(ans<<3)+(ans<<1)+(s[i]^48);
int money=read();
int k=ans;
c[di[k]]=money-a[k];
up(di[k]);down(di[k]);
a[k]=money;
}
}
return 0;
}
/**************************************************************
Problem: 1994
User: lichengtai
Language: C++
Result: 正确
Time:137 ms
Memory:6784 kb
****************************************************************/