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;
}
}