现在的位置: 首页 > 综合 > 正文

2013 ACM/ICPC 长沙赛区现场赛A题 解题报告

2014年02月03日 ⁄ 综合 ⁄ 共 1023字 ⁄ 字号 评论关闭

题目链接: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;
}

提示::本人很少写结题报告,表达能力有限,,代码也烂有不对的欢迎指出

抱歉!评论已关闭.