hdu 4791 长沙现场赛A题

来源:互联网 发布:录屏软件画中画 编辑:程序博客网 时间:2024/04/30 15:08

题意:打印纸张,随着张数的增加,价格非递增,给出m个询问打印的张数,求最小的花费。

思路:找到张数所在的区间,最大的花费就是该区间的价格*张数,如果要打印多余的张数,就在后面的区间找,因为后边的区间都是张数大于目标张数,所以去区间的最小值,应为价格是非递增的,张数是递增的,所以要找区间的张数*价格的最小值,用线段树就可以。。。

写完了,才想到其实没这么复杂,可以直接从后往前求每个区间右边的最小值,记录一下,直接用就可以了。


#include<stdio.h>#include<string.h>const int N=100100;__int64 cnt[N],num[N];int n;struct Tree{    int L,R;    __int64 mw;}T[N*4];__int64 min(__int64 a,__int64 b){    if(a>b)return b;    return a;}void buildTree(int L,int R,int id){    T[id].L=L;T[id].R=R;    if(L==R)    {        T[id].mw=cnt[L]*num[L];        return ;    }    int li,ri,mid;    mid=(L+R)>>1;    li=id<<1;ri=li|1;    buildTree(L,mid,li);    buildTree(mid+1,R,ri);    T[id].mw=min(T[li].mw,T[ri].mw);}__int64 find(int L,int R,int id){    if(T[id].L==L&&T[id].R==R)        return T[id].mw;    int li=id<<1,ri=li|1,mid=(T[id].L+T[id].R)>>1;    if(R<=mid)return find(L,R,li);    else if(L>mid) return find(L,R,ri);    else return min(find(L,mid,li),find(mid+1,R,ri));}int findnum(__int64 w){    int L,R,mid,flag;    L=1;R=n;flag=1;    while(L<=R)    {        mid=(L+R)>>1;        if(num[mid]<=w)        {            flag=mid;            L=mid+1;        }        else R=mid-1;    }    return flag;}int main(){    int i,j,m,t;    __int64 sum,w;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        for(i=1;i<=n;i++)            scanf("%I64d%I64d",&num[i],&cnt[i]);        buildTree(1,n,1);        while(m--)        {            scanf("%I64d",&w);            j=findnum(w);            if(j==n){printf("%I64d\n",cnt[j]*w);continue;}            sum=find(j+1,n,1);            printf("%I64d\n",min(sum,cnt[j]*w));        }    }    return 0;}




#include<stdio.h>#include<string.h>const int N=100005;__int64 cnt[N],num[N],minw[N];int n;__int64 min(__int64 a,__int64 b){    if(a>b)return b;    return a;}int findnum(__int64 w){    int L,R,mid,flag;    L=1;R=n;flag=1;    while(L<=R)    {        mid=(L+R)>>1;        if(num[mid]<=w)        {            flag=mid;            L=mid+1;        }        else R=mid-1;    }    return flag;}int main(){    int i,j,m,t;    __int64 w;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        for(i=1;i<=n;i++)            scanf("%I64d%I64d",&num[i],&cnt[i]);        minw[n]=num[n]*cnt[n];        for(i=n;i>=2;i--)        {            minw[i-1]=minw[i];            if(num[i]*cnt[i]<minw[i])                minw[i-1]=num[i]*cnt[i];        }        while(m--)        {            scanf("%I64d",&w);            j=findnum(w);            if(j==n){printf("%I64d\n",cnt[j]*w);continue;}            printf("%I64d\n",min(cnt[j]*w,minw[j+1]));        }    }    return 0;}



原创粉丝点击