有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?
<?php
error_reporting(E_ALL ^ E_NOTICE);
class mostarea{
function print_area($n,$a,$k,$d){
//引用 数据
//$n=$this->n;
//$a=$this->a;
//$k=$this->k;
//$d=$this->d;
$s_value="1";//
/*+++
/* 要想选出最大值能力值,一定是最大能力值相乘,所以问题就变成了找到满足d的值
/* 先排序,选出最大的能力值 如果第二大的值的编号满足d,则用第二大值,不满足则选一个最大值
+++*/
$a_order=$a;
arsort($a_order);//arsort按降序排序,不改变键值
//按最大值取出最大值及对应的编号
$i=0;
foreach($a_order as $key=>$val){
$a_order_arr[$i]["key"]=$key;//
$a_order_arr[$i]["val"]=$val;//
$i++;
}
if($d<0){
$d=abs($d);//对差值取正,
}
//从最大值排序开始计算
for($i=0;$i<$n;$i++){//
$m=0;
$k_v=1;
for($sc=0;$sc<$k_v;$sc++){//
if($sc==0){
$max_val[$i][$m]["val"]=$a_order_arr[$i]["val"];//最大值
$max_val[$i][$m]["key"]=$a_order_arr[$i]["key"];//最大值
}
//$max_key[$i][$m]=$a_order_arr[$i]["key"];//最大值对应的编号
//在这个最大值范围内取出$a_key[$i]-$d到 $a_key[$i]+$d
$left_one=$max_val[$i][$m]["key"]-$d;
if($sc==0){
$left_one=$max_val[$i][$m]["key"]-$d;
}else{
$left_one=$max_val[$i][count($max_val[$i])-1]["key"]-$d;
}
//$new_arr_1[$i]=array_slice($a,$left_one,(2*$d+1));//下面相当于函数array_slice
$nf=0;
if($left_one<0){
$left_one=0;
}
$get_count[$i]=$left_one+2*$d+1;
if(($n-1)<$get_count[$i]){
switch($n){
case "1":
$get_count[$i]=1;
break;
default:
$get_count[$i]=$n;
}
}
if($sc==0){
$new_a[$i]=$a;//将当前数组赋值给一个新的数组
}else{
$new_a[$i]=$new_a[$i];//
}
$new_a[$i][$max_val[$i][$m]["key"]]="";//置空当前值
//show($new_a);
for($f=$left_one;$f<$get_count[$i];$f++){
//if($new_a[$i][$f]){
$new_arr[$i][$sc][$nf]["val"]=$new_a[$i][$f];
$new_arr[$i][$sc][$nf]["key"]=$f;
$nf++;
// }
}
if(0<$sc){
//show($new_arr);
}
if($sc==0){
//show($new_arr);
}
//计算新数组满足d条件的第2大值
if(1<count($new_arr[$i][$sc])){
arsort($new_arr[$i][$sc]);
}
if(empty($new_arr[$i][$sc]) ||count($new_arr[$i][$sc])==1){//数组key最左只能是0
$s_count=0;//
}else{
$s_count=1;
}
//show($new_arr[$i][$sc]);
for($s=0;$s<$s_count;$s++){
//当前指针的的值和key
if(0==$s){
$second_val_arr[$i][$s]=current($new_arr[$i][$sc]);
}else{
$second_val_arr[$i][$s]=next($new_arr[$i][$sc]);
}
$second_val[$i][$s]=$second_val_arr[$i][$s]["val"];
$second_key[$i][$s]=$second_val_arr[$i][$s]["key"];
//单再次排列的值满足d
$d_value[$i][$s]=abs(($max_val[$i][$m]["key"])-$second_key[$i][$s]);
if($d_value[$i][$s]<=$d){
//if(count($max_val[$i])<=$k){
$m=$m+1;
$max_val[$i][$m]["val"]=$second_val[$i][$s];
$max_val[$i][$m]["key"]=$second_key[$i][$s];
if(count($max_val[$i])==$k){
break;
}
}else{
if($s_count<=$n){
$s_count++; //这个范围不满足继续找
}
}
}
//show(count($max_val[$i]));
if(count($max_val[$i])<$k && $k_v<=$n){
$k_v++;
}
}
//按原来key值排序
foreach($max_val[$i] as $o_val){//
$key_array[$i][]=$o_val['key'];
}
array_multisort($key_array[$i],SORT_ASC,SORT_NUMERIC,$max_val[$i]);
//计算乘积
$last_val[$i]=1;
for($cj=0;$cj<$k;$cj++){
if($max_val[$i][$cj]["val"]){
$last_val[$i]=$last_val[$i]*$max_val[$i][$cj]["val"];
$max_val[$i][$cj]["key"]=$max_val[$i][$cj]["key"]+1;//key代表数组,真实从1开始
$last_key[$i]=($last_key[$i] || $last_key[$i]==0)?$last_key[$i].",".$max_val[$i][$cj]["key"]:$max_val[$i][$cj]["key"];
}
}
$obj[$i]["val"]=$last_val[$i];
$obj[$i]["key"]=$last_key[$i];
}
return $obj;
}
function get_val(){
$a=new mostarea();
$n=5;
$a=array("1","10","5","22","99");
$k=2;
$d=1;
$value=$this->print_area($n,$a,$k,$d);
rsort($value);
echo "输入:";
echo "<br>";
echo "---".$n."排";
echo "<br>";
echo "---".implode($a," , ");
echo "<br>";
echo "--- 选取".$k."人";
echo "<br>";
echo "---差值不超过:".$d;
echo "<br>";
echo "选取结果:";
echo "<br>";
echo "<<<"."最大值:".$value[0]["val"];
echo "<br>";
echo "<<<"."编号选择:".$value[0]["key"];
}
}
$a=new mostarea();
$a->get_val();