• php实现 合唱队形(算法想清楚在动)


    php实现  合唱队形(算法想清楚在动)

    一、总结

    一句话总结:写一个最长递增子序列的函数,正反两遍扫一下就好。写函数这样不容易错。这个好像可以用二分来优化。

    1、算法题怎么提高正确率和节约时间?

    算法想清楚了在做,不然会出现莫名其妙,稀奇古怪的错误。

    2、php中如何填充数组?

    用array_fill();

    array array_fill ( int $start_index , int $num , mixed $value )

    $a = array_fill(5, 6, 'banana');

    Array
    (
        [5]  => banana
        [6]  => banana
        [7]  => banana
        [8]  => banana
        [9]  => banana
        [10] => banana
    )

    二、合唱队形

    题目描述

    计算最少出列多少位同学,使得剩下的同学排成合唱队形

    说明:

    N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。 
    合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,   则他们的身高满足存在i(1<=i<=K)使得T1<T2<......<Ti-1<Ti>Ti+1>......>TK。 
    你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。 

    输入描述:

    整数N

    输出描述:

    最少需要几位同学出列

    示例1

    输入

    复制
    8
    186 186 150 200 160 130 197 200
    

    输出

    复制
    4

    代码一:

     1 <?php
     2 //谋而后动,之前算法有问题
     3 while($n=trim(fgets(STDIN))){
     4 $numStr=trim(fgets(STDIN));
     5 $arr=explode(' ',$numStr);
     6 for($i=0;$i<$n;$i++){
     7     $gao[$i]=1;
     8     $gaoRev[$i]=1;
     9 }
    10 //print_r($arr);
    11 for($i=0;$i<$n;$i++){//遍历每一个人
    12     for($j=0;$j<$i;$j++){//遍历他们前面的
    13         if($arr[$i]>$arr[$j]&&$gao[$j]+1>$gao[$i]) $gao[$i]=$gao[$j]+1;
    14     }
    15 }
    16 for($i=$n-1;$i>0;$i--){//遍历每一个人
    17     for($j=$n-1;$j>$i;$j--){//遍历他们前面的
    18         if($arr[$i]>$arr[$j]&&$gaoRev[$j]+1>$gaoRev[$i]) $gaoRev[$i]=$gaoRev[$j]+1;
    19     }
    20 }
    21 for($i=0;$i<$n;$i++) $ans[$i]=$n+1-$gao[$i]-$gaoRev[$i];
    22 //print_r($gao);
    23 //print_r($gaoRev);
    24 echo min($ans).PHP_EOL;
    25 }
    26 
    27 ?>

    代码二:

     1 <?php
     2  
     3 function lis($arr){
     4     $dp = array_fill(0,count($arr),1);
     5     $ends = array_fill(0,count($arr),0);
     6     $l = 0; $r = 0; $right = 0;
     7     $ends[0] = $arr[0];
     8     for($i = 1; $i<count($arr);$i++) {
     9         $l = 0;
    10         $r = $right;
    11         while ($l <= $r) {
    12             $mid = floor(($l + $r)/2);
    13             if($arr[$i]>$ends[$mid]) {
    14                 $l = $mid + 1;
    15             }else {
    16                 $r = $mid - 1;
    17             }
    18         }
    19         $right = max($right,$l);
    20         $dp[$i] = $l+1 ;
    21         $ends[$l] = $arr[$i];
    22     }
    23     return $dp;
    24 }
    25  
    26 //两遍最长递增子序列 和最大
    27 while (fscanf(STDIN,"%d",$N)) {
    28     $T = explode(" ",trim(fgets(STDIN)));
    29     $lis1 = lis($T);
    30     $lis2 = lis(array_reverse($T));
    31     $lis2 = array_reverse($lis2);
    32     for($i=0;$i<$N;$i++){
    33         $lis1[$i] += $lis2[$i];
    34     }
    35     $max = max($lis1);
    36     /* $dp1 = array_fill(0,$N,1);
    37     $dp2 = array_fill(0,$N,1);
    38     for($i=0;$i<$N;$i++){
    39         for($j=$i-1;$j>=0;$j--){
    40             if($T[$j]<$T[$i]&&$dp1[$j]+1>$dp1[$i])
    41                 $dp1[$i] = $dp1[$j]+1;
    42         }
    43     }
    44     $Tr = array_reverse($T);
    45     for($i=0;$i<$N;$i++){
    46         for($j=$i-1;$j>=0;$j--){
    47             if($Tr[$j]<$Tr[$i]&&$dp2[$j]+1>$dp2[$i])
    48                 $dp2[$i] = $dp2[$j]+1;
    49         }
    50     }
    51     $dp2 = array_reverse($dp2);
    52      
    53     $max = -1;
    54     $sum = 0;
    55     for($i=0;$i<$N;$i++){
    56         $sum = $dp1[$i]+$dp2[$i];
    57         if($sum>$max)
    58             $max = $sum;
    59     } */
    60     echo ($N-$max+1)."
    ";
    61  
    62 }
    63 ?>
     
  • 相关阅读:
    linux 学习之七-部分ssh命令
    揭秘淘宝286亿海量图片存储与处理架构
    大型网站后台架构的演变
    Linux学习之六-Yum命令的使用
    res://ieframe.dll/acr_error.htm 纯手动解决方法
    VS2013启动项目调试的时候会启动本地IIS
    linux学习之(六)-主机名、网络IP的配置与查看
    deployment.yaml 带同步时区
    Deployment
    mysql.yaml
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/9228186.html
Copyright © 2020-2023  润新知