您的位置:首页 > 其它

BZOJ2465: [中山市选2009]小球

2016-04-12 08:02 351 查看
看错两次题目

第一次以为是01背包

第二次以为是每个杯子一个询问

日狗..

一堆网络流过得。。并不是很理解QWQ

其实直接二分就好了啦

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
inline int min(int a,int b)
{return a>b?b:a;
}
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}

int F[301][301];
int Val[301];
struct Query
{
int id,MaxV,MaxQ,ans1,ans2;
inline friend bool operator <(Query a,Query b)
{return a.id<b.id;}
}Q[201];

inline bool cmp(Query a,Query b)
{
return a.MaxQ>b.MaxQ;
}
int Pre[301];
int main()
{
int n,m;
int i,j=0;
while(true)
{
memset(F,0,sizeof(F));
read(n),read(m);
if(n==0)break;
for(i=1;i<=n;i++)
read(Val[i]);
sort(Val+1,Val+1+n);
for(int i=1;i<=n;i++)Pre[i]=Pre[i-1]+Val[i];
Val[n+1]=328787837;
for(i=1;i<=m;i++)
read(Q[i].MaxV),read(Q[i].MaxQ),Q[i].id=i;
sort(Q+1,Q+1+m,cmp);
int Cur=n+1;
int A1=0,A2=0;
for(i=1;i<=m;i++)
{

int as,l=0,r=n+1,mid;
while(l<=r)
{
mid=l+r>>1;
if(Val[mid]>Q[i].MaxQ)r=mid-1;
else l=mid+1,as=mid;
}
Q[i].ans1=min(min(as,Q[i].MaxV),Cur-1);
Q[i].ans2=Pre[min(as,Cur-1)]-Pre[min(as,Cur-1)-Q[i].ans1];
Cur=min(as,Cur-1)-Q[i].ans1+1;
A1+=Q[i].ans1;
A2+=Q[i].ans2;
}
printf("%d %d\n",A1,A2);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: