[编程题]健身
因为公司有免费健身福利,快手程序员老铁们都很爱健身,而且他们健身时像工作一样充满效率。
他们把健身过程神奇的简化了出来:健身有N种锻炼方式可选,器材可看成在一条直线上。
每种锻炼方式距门口Xi米,因为有的器材上可以支持多种锻炼方式,因此有可能出现两种锻炼方式的距离是一样的,即Xa = Xb。
老铁们一进健身房门口就开启健身形态,每走1米,就能获得1点锻炼效果值,而每种锻炼方式也有Ei的效果值,锻炼的过程就是从门口走到某种锻炼方式锻炼,然后到下一个方式锻炼,最后返回门口的过程。需要注意的是,锻炼过程中老铁们不会为了获得效果而刻意走回头路。
老铁们很想知道如果想选择某几种锻炼方式,怎样获得最大锻炼效果。
输入描述:
第一行N,表示锻炼方式的个数
第二行N个整数,表示每种锻炼方式距门口的距离
第三行N个整数,表示每种锻炼方式的效果值
输出描述:
N个整数,第k行表示选择k种锻炼方式时获得的最大锻炼效果
示例1
输入
5
1 2 3 4 5
1 1 1 1 1
输出
11
12
13
14
15
说明
对于样例第一行,老铁选择去第5种锻炼方式,考虑来回路程,一共获得5+1+5点锻炼效果值
备注:
对于所有数据,N <= 100,000,输出结果在32位整数范围内
思路:
e
i
ei
ei是能量,
d
i
s
t
dist
dist是距离
要求解
m
a
x
(
e
1
+
e
2
+
e
3
+
…
+
e
n
)
+
m
a
x
(
d
i
s
t
∗
2
)
max(e1+e2+e3+…+en)+max(dist*2)
max(e1+e2+e3+…+en)+max(dist∗2)
而
d
i
s
t
dist
dist和
e
1
e1
e1有关,
即求解
m
a
x
(
e
1
,
e
2
,
e
3
+
e
n
−
1
)
+
m
a
x
(
e
n
)
+
m
a
x
(
d
i
s
t
∗
2
)
max(e1,e2,e3+en-1)+max(en)+max(dist*2)
max(e1,e2,e3+en−1)+max(en)+max(dist∗2)
此时可看出,前n-1个一定是val的最大值,而
m
a
x
(
e
n
)
+
m
a
x
(
d
i
s
t
∗
2
)
max(en)+max(dist*2)
max(en)+max(dist∗2)可以看到要么是
1.
e
n
+
d
i
s
t
∗
2
en+dist*2
en+dist∗2的和的值最大,否则
2.
v
a
l
val
val最大,
d
i
s
t
dist
dist是前面的某个n的值。
所以应该找出前
k
−
1
个
k-1个
k−1个最大的E,剩下的如果器材A的
d
d
d比前面选的
k
−
1
k-1
k−1个器材要大,那么最后一个器材就选A;否则,就选value第k大的器材。
用python比较容易过,这里的c的排序和查找部分我人工优化得不太好,但是思路是这样,目前用快排(粗糙版)加上简单查找可以实现80%Access
python版本100%通过:
N=int(input())
distance = input().split()
exp = input().split()
max_to_choose=[]
for i in range(0,N):
info={'dist':int(distance[i]),'exp':int(exp[i])}
max_to_choose.append(info)
max_exp=sorted(max_to_choose,key=lambda info:info['exp'],reverse=True) # 按照健身效果排序,由于排序保证是稳定的。所以健身效果相同时,距离大的在后面
max_dist=0
kmax_save=0
kmax_exp=[]
save_index=0
for i in range(0,N):
if(i>0):
kmax_save=kmax_save+max_exp[i-1]['exp']
kmax_exp.append(kmax_save)
if(max_exp[i-1]['dist']>max_dist):
max_dist=max_exp[i-1]['dist']
else:
kmax_exp.append(0)
maxval=0
value=0
if(save_index<=i):
for k in range(i,N):
value=max_exp[k]['exp']+max_exp[k]['dist']*2
if(value>maxval):
maxval=value
save_index=k
# 从剩下的里找出2d+V最大的的器材A
if(max_dist<max_exp[save_index]['dist']):
kmax_exp[i]=kmax_exp[i]+2*max_exp[save_index]['dist']+max_exp[save_index]['exp']
else:
kmax_exp[i]=kmax_exp[i]+2*max_dist+max_exp[i]['exp']
for km in kmax_exp:
print(km)
c代码80%通过:
#include <stdio.h>
#include <stdlib.h>
void quick_sort(int s,int k,int a[][2])
{
if(s<k)
{
int i=s,j=k;
int tmp=a[i][0];
int tmp2=a[i][1];
while(i<j)
{
while(i<j && a[j][0]<tmp)
{
j--;
}
if(i<j)
{
a[i][0]=a[j][0];
a[i][1]=a[j][1];
i++;
}
while(i<j && a[i][0]>=tmp)
{
i++;
}
if(i<j)
{
a[j][0]=a[i][0];
a[j][1]=a[i][1];
j--;
}
}
a[i][0]=tmp;
a[i][1]=tmp2;
quick_sort(s,i-1,a);
quick_sort(i+1,k,a);
}
}
void print(int a[][2],int p,int e)
{
int i=0;
for(i=p; i<=e; i++)
{
printf("exp:%d dist:%d\n",a[i][0],a[i][1]);
}
printf("\n");
}
void print_re(int kmax_exp[])
{
int i=0;
while(kmax_exp[i])
{
printf("%d\n",kmax_exp[i]);
i++;
}
}
int info[100000][2]= {0};
int kmax_exp[100000]= {0};
int choosed=0;
int main()
{
int i=0,n=0;
scanf("%d",&n);
for(i=0; i<n; i++)
{
scanf("%d",&info[i][1]);
}
for(i=0; i<n; i++)
{
scanf("%d",&info[i][0]);
}
quick_sort(0,n-1,info); //复杂度n2
//print(info,0,n-1);
int k=0;
int max_dist=0;
int kmax_save=0;
int save_index=-1;
for(i=0; i<n; i++)
{
//先选k-1个value最大的器材
if(i>0) //由于前k-1个始终相同,直接保存结果
{
kmax_save=kmax_save+info[i-1][0];
kmax_exp[i]=kmax_save;
choosed=i-1; //标记前i-1个为已经选择
if(info[i-1][1]>max_dist)
{
max_dist=info[i-1][1];//保存最大距离
}
}
//for(k=0;k<n;k++){
// printf("%d ",choosed[k]);
//}
//printf("\n");
//print_re(kmax_exp);
int exp=info[i][0]; //保存第k大的经验值
int maxval=0;
int value=0;
//只有当en+dist*2最大的值被作为前面的
//选择了之后才需要重新选择。从第k个开始找。
if(save_index<=i)
{
for(k=i; k<n; k++)
{
//从剩下n-i个里面的选择一个en+dist*2最大的
value=info[k][0]+info[k][1]*2;
if(value>maxval)
{
maxval=value;
save_index=k;//保存选择的这个剩下最大的器材的索引
}
}
}
//printf("maxdist:%d maxval: %d save_index:%d \n",max_dist,maxval,save_index);
if(max_dist<info[save_index][1])
{
kmax_exp[i]=kmax_exp[i]+2*info[save_index][1]+info[save_index][0];
}
else
{
kmax_exp[i]=kmax_exp[i]+2*max_dist+exp;
}
}
print_re(kmax_exp);
return 0;
}

本文探讨了如何为健身者设计最优的健身路径,通过选取特定数量的锻炼方式以最大化锻炼效果值。利用排序和动态规划的方法,文章提供了一种高效的算法解决方案,并给出了Python及C语言的实现代码。
1841

被折叠的 条评论
为什么被折叠?



