推销员

 http://icpc.upc.edu.cn/problem.php?cid=1688&pid=3

X=1:向住户5推销,往返走路的疲劳值为5+5,推销的疲劳值为5,总疲劳值为15。

X=2:向住户4、5推销,往返走路的疲劳值为5+5,推销的疲劳值为4+5,总疲劳值为5+5+4+5=19。

X=3:向住户3、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值3+4+5,总疲劳值为5+5+3+4+5=22。

X=4:向住户2、3、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值2+3+4+5,总疲劳值5+5+2+3+4+5=24。

X=5:向住户1、2、3、4、5推销,往返走路的疲劳值为5+5,推销的疲劳值1+2+3+4+5,总疲劳值5+5+1+2+3+4+5=25。
 

这道题用贪心,然后每选择一个点累加进答案后,前面的点的距离都没用了,所以前面的直接扔进堆里。再扫描这个点之后的,计算权值,如果>堆顶权值,把它与这个点之间的所有点都扔进去… 
复杂度不稳定,就是个卡时间算法 

#include<cstdio>
#include<queue>
using namespace std;
int n,i,j,k,l,ans,t,k1;
priority_queue<pair<int,int> >q;
pair<int,int>a[1000010];
int main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++)
        scanf("%d",&a[i].second);
    for (i=1; i<=n; i++)
        scanf("%d",&a[i].first);
    for (i=1; i<=n; i++)
        if (a[i].second*2+a[i].first>0)
        {
            ans=a[i].second*2+a[i].first;
            k=i;
        }
    for (i=1; i<k; i++)
        q.push(a[i]);
    printf("%d\n",a[k].second*2+a[k].first);
    for (i=2; i<=n; i++)
    {
        t=k;
        k1=q.top().first;
        for (j=k+1; j<=n; j++)
            if((a[j].second-a[k].second)*2+a[j].first>k1)
            {
                k1=(a[j].second-a[k].second)*2+a[j].first;
                t=j;
            }
        a[t].first+=(a[t].second-a[k].second)*2;
        if(k!=t)
            q.push(a[t]);
        for (j=k+1; j<=t-1; j++)
            q.push(a[j]);
        ans+=q.top().first;
        q.pop();
        printf("%d\n",ans);
        k=t;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值