hdu 4791 长沙现场赛A题
2013-12-02 07:38
253 查看
题意:打印纸张,随着张数的增加,价格非递增,给出m个询问打印的张数,求最小的花费。
思路:找到张数所在的区间,最大的花费就是该区间的价格*张数,如果要打印多余的张数,就在后面的区间找,因为后边的区间都是张数大于目标张数,所以去区间的最小值,应为价格是非递增的,张数是递增的,所以要找区间的张数*价格的最小值,用线段树就可以。。。
写完了,才想到其实没这么复杂,可以直接从后往前求每个区间右边的最小值,记录一下,直接用就可以了。
思路:找到张数所在的区间,最大的花费就是该区间的价格*张数,如果要打印多余的张数,就在后面的区间找,因为后边的区间都是张数大于目标张数,所以去区间的最小值,应为价格是非递增的,张数是递增的,所以要找区间的张数*价格的最小值,用线段树就可以。。。
写完了,才想到其实没这么复杂,可以直接从后往前求每个区间右边的最小值,记录一下,直接用就可以了。
#include<stdio.h> #include<string.h> const int N=100100; __int64 cnt ,num ; 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 ,num ,minw ; 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 =num *cnt ; 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; }
相关文章推荐
- HDU 4791 Alice's Print Service(2013长沙区域赛现场赛A题)
- HDU 4793 Collision(2013长沙区域赛现场赛C题)
- HDU 4793 Collision (解二元一次方程) -2013 ICPC长沙赛区现场赛
- 2013年长沙区域赛-HDU 4791-Alice's Print Service
- HDU 4800/zoj 3735 Josephina and RPG 2013 长沙现场赛J题
- HDU 4793 Collision (2013长沙现场赛,简单计算几何)
- HDU 4791 Alice's Print Service (2013长沙现场赛,二分)
- hdu 4801 长沙现场赛K题
- 2013 长沙现场赛 K (Pocket Cube)
- HDU - 5980 Find Small A (ICPC2016 大连现场,一点简单的数学小结论)
- HDU 5112 A Curious Matt(2014亚洲区北京站现场赛)
- HDU 5137 How Many Maos Does the Guanxi Worth(2014亚洲区广州站现场赛)
- HDU - 4571 Travel in time 2013长沙邀请赛
- Ugly Problem(hdu 5920 && 2016ICPC长春现场赛模拟题)
- HDU-4567-思维-Brilliant Programmers Show -13长沙邀请赛
- HDU 5120 Intersection (计算几何)2014ICPC 北京站现场赛
- HDU 4463 Outlets 2012年亚洲区域赛杭州赛区现场赛K题
- HDU 4565 -- So Easy! 数学 && 2013 ACM-ICPC 长沙赛区全国邀请赛 A题
- hdu 5078(2014鞍山现场赛 I题)
- hdu 4788 (2013成都现场赛 H题)