题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3726
题意容易理解:就是一个打印分段收费政策,印的越多,单张价格越低,输入需要印刷的数量,求最小印刷费用
思路:由于印的张数越多,单价越便宜
可以对数据进行预处理:
先求每一种价格对应的最小费用,也就是张数刚刚好时的费用,最小费用sp=s[i]*p[i];
然后求大于每一个基础数量s[i]后面的所有对应最小费用,用mini[i]保存。
这样对于每组输入,只要对比印刷张数刚刚够的价格和s[i】后的最小价格,取小者就是答案。
附上AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
long long mini[100005];
long long s[100005],p[100005],sp[100005];
int main()
{
int t,i,j,m,n;
long long mi,pa,ans,pri;
long long id;
scanf("%d",&t);
while(t--)
{
memset(s,0,sizeof(s));
memset(sp,0,sizeof(sp));
memset(p,0,sizeof(p));
scanf("%d %d",&n,&m);
for(i=1; i<=n; i++)
{
scanf("%lld %lld",&s[i],&p[i]);
}
mi=sp[n]=s[n]*p[n];
for(i=n-1; i>=1; i--)
{
sp[i+1]=s[i+1]*p[i+1];
if(sp[i+1]<mi)
{
mini[i]=sp[i+1];
mi=sp[i+1];
}
else mini[i]=mi;
}
for(i=0; i<m; i++)
{
scanf("%lld",&pa);
id=upper_bound(s+1,s+n+1,pa)-s;
if(id==n+1)
{
printf("%lld\n",pa*p[n]);
continue;
}
if(id==1) ;
else id=id-1;
pri=p[id]*pa;
if(pri>mini[id]) ans=mini[id];
else ans=pri;
printf("%lld\n",ans);
}
}
return 0;
}
提示::本人很少写结题报告,表达能力有限,,代码也烂有不对的欢迎指出