推销员基础解法c++

题目描述

  阿明是一名推销员,他奉命到螺丝街推销他们公司的产品。螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户。螺丝街一共有N家住户,第i家住户到入口的距离为Si米。由于同一栋房子里可以有多家住户,所以可能有多家住户与入口的距离相等。阿明会从入口进入,依次向螺丝街的X家住户推销产品,然后再原路走出去。

  阿明每走1米就会积累1点疲劳值,向第i家住户推销产品会积累Ai点疲劳值。阿明是工作狂,他想知道,对于不同的X,在不走多余的路的前提下,他最多可以积累多少点疲劳值。

输入格式

  第一行有一个正整数N,表示螺丝街住户的数量。

  接下来的一行有N个正整数,其中第i个整数Si表示第i家住户到入口的距离。数据保证S1≤S2≤...≤Sn<10^8

  接下来的一行有N个正整数,其中第i个整数Ai表示向第i户住户推销产品会积累的疲劳值。数据保证Ai<10^3

输出格式

  输出N行,每行一个正整数,第i行整数表示当X=i时,阿明最多积累的疲劳值。

输入样例

5

1 2 2 4 5

5 4 3 4 1

输出样例

12 17 21 24 27

 

数据规模

  对于20%的数据,1≤N≤20;

  对于40%的数据,1≤N≤100;

  对于60%的数据,1≤N≤1000;

  对于100%的数据,1≤N≤100000。

代码

#include<stdio.h>

long MAX(long a,long b)
{
	return a>b?a:b;
}

int main()
{
	long N;
	scanf("%ld",&N);
	long a[2][N];//存输入的两行数据
	long flag,flag0;//存数组下标,前者存上次取最大值的数所对应的下标,后者存这次取最大值的数所对应的下标
	long max0,max;
	long i,k,X,j,m;
	long record;//记录每次的疲劳度
	long distance;//存每次最远的距离 
	for(i=0;i<2*N;i++)
	{
	if(i<N)	scanf("%ld",&a[0][i]);
	else if(i<2*N) scanf("%ld",&a[1][i-N]);
	}//读入数据 
	
	max=0;
	for(k=0;k<N;k++)
	{
		max=max>(2*a[0][k]+a[1][k])?max:(2*a[0][k]+a[1][k]);
		if (max==2*a[0][k]+a[1][k])
		{
			flag=k;
		}
	}
	printf("%ld\n",max);//x=1时 
	
	record=a[1][flag];
	a[1][flag]=0;
	
	for(X=2;X<=N;X++)//x>=2时 
	{
		max0=0;
		m=flag;
		distance=a[0][flag];
	    for(j=0;j<N;j++)
		{
		  m=flag;
		  if(a[0][j]<a[0][flag])//考虑距离小于原来最大距离的数集 
			{
			max0=max0>(a[1][j]+max)?max0:(a[1][j]+max);
			if(max0==(a[1][j]+max)) flag0=j;
			}
		  if(a[0][j]>a[0][flag])//考虑距离大于原来最大距离的数集
			{
			max0=max0>(2*a[0][j]+a[1][j]+record)?max0:(2*a[0][j]+a[1][j]+record);
			if(max0==(2*a[0][j]+a[1][j]+record)) {
			flag0=j;
			distance=a[0][j];
		    }
			}
		}
		max=max0;
		
		record=max-2*distance;//记录疲劳度	
		printf("%ld\n",max);
	    a[1][flag0]=0;	//对取的数的疲劳度清零 
	}
	return 0;
}

ps:oj上超时了,希望大佬们指点一二

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Detachment_destin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值