华为OJ——合唱队

合唱队

题目描述

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

说明:

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

输入描述:

整数N

输出描述:

最少需要几位同学出列

输入例子:

8

186 186 150 200 160 130 197 200

输出例子:

4

解答代码:

#include<iostream>
#include<cstdio>
#include<fstream>
#define LEN 1024
using namespace std;

//当前各元素作为最大递增序列的长度或者最为递减序列的长度
int liss[LEN];
//记录前驱元素,记录当前元素作为最大递增序列或者最大递减序列的前驱结点
int pre[LEN];

//求解最大递增序列
int LISSIncre(int array[],int result[],int length)
{
    int i,j,index,max;
    //初始化liss长度数组和pre前驱数组
    for(i=0; i<length; i++)
    {
        liss[i]=1;
        pre[i]=i;
    }
    for(i=1,max=1,index=0; i<length; i++)
    {
        for(j=0; j<i; j++)
        {
            if(array[j]<array[i] && liss[j]+1 > liss[i])
            {
                liss[i]=liss[j]+1;
                pre[i]=j;
                if(liss[i]>max)
                {
                    max=liss[i];
                    index=i;
                }
            }
        }
    }
    //得到最大递增序列
    i=max-1;
    while(pre[index]!=index)
    {
        result[i--]=array[index];
        index=pre[index];
    }
    result[i]=pre[index];
    return max;
}

//求解最大递减序列
int LISSDec(int array[],int result[],int length)
{
    int i, j, index, max;
    for(i = 0; i < length; ++i)
    {
        liss[i] = 1;
        pre[i] = i;
    }
    for(i = 1, max = 1, index = 0; i < length; ++i)
    {
        for(j = 0; j < i; ++j)
        {
            if(array[j] > array[i] && liss[j] + 1> liss[i])
            {
                liss[i] = liss[j] + 1;
                pre[i] = j;
                if(max < liss[i])
                {
                    max = liss[i];
                    index = i;
                }
            }
        }
    }
    i = max - 1;
    while(pre[index] != index)
    {
        result[i--] = array[index];
        index = pre[index];
    }
    result[i] = array[index];
    return max;
}

int main()
{
    int N=0;
    int array[1024];
    int index=0;
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    while(fin>>N)
    {
        for(index=0; index<N; index++)
            fin>>array[index];
        int arrayLeft[1024];
        int arrayRight[1024];

        int resultLeft[1024];
        int resultRight[1024];

        int left=0;
        int right=0;

        int i,j,k;
        int max1=0,max2=0,max=0;
        for(i=1; i<N-1; i++)
        {
            int temp=array[i];
            //左右两边的数组元素个数
            left=i+1;
            right=N-i;

            //左边的数组
            for(j=0; j<=i; j++)
            {
                arrayLeft[j]=array[j];
            }
            //右边的数组
            for(k=0,j=i; j<N; k++,j++)
            {
                arrayRight[k]=array[j];
            }

            max1=LISSIncre(arrayLeft,resultLeft,left);
            max2=LISSDec(arrayRight,resultRight,right);

            if(temp==resultLeft[max1-1] && temp==resultRight[0])
            {

                if(max1+max2-1>max)
                    max=max1+max2-1;
            }
        }
        cout<<N-max<<endl;
    }

    fin.close();
    fout.close();
    return 0;
}

我的设计思路很简单,当数据大于等于三个时,从第i个开始(0<=i<=length-2),将数组分成左右2个部分,左边求解最大递增序列,右边求解最大递减序列,当然array[i]这个元素需要满足是左边最大递增序列的最后一个元素,是右边最大递减序列的第一个元素。为了测试方便我把测试案例放到了文件中,通过读文件读入测试案例。但是实际上测试的结果与给出的结果不一样,我的测试结果是622

以下是改组测试用例:

692 160 459 759 192 1251 1070 77 365 428 291 1013 521 86 121 87 731 1249 238 861 605 780 103 501 1380 326 683 506 1067 949 625 148 1106 937 659 28 1059 826 98 938 1175 1270 161 790 939 1235 729 1232 1221 390 744 1245 1298 157 391 881 812 1202 714 1287 1126 140 783 717 144 889 795 713 12 151 137 458 374 38 256 1058 1052 642 557 240 294 473 1077 815 153 682 384 520 1016 821 556 418 890 1308 1042 704 1203 1362 168 822 1362 973 282 1256 1229 235 463 408 708 920 950 1193 285 805 408 445 1091 980 761 373 48 588 1086 933 476 874 1166 513 1165 532 129 135 1022 236 1266 1370 365 22 583 1261 756 908 1070 322 1148 1041 935 601 548 784 1270 1306 1166 31 203 1230 523 1336 590 596 673 199 456 827 544 48 270 249 336 209 926 464 402 1074 135 582 1014 750 758 509 380 925 598 241 706 768 729 467 741 1202 49 1206 297 827 1139 1100 372 312 1014 328 678 303 245 382 1228 7 339 215 1193 1214 1007 582 613 695 338 442 196 54 395 232 815 573 807 1199 519 1016 53 1267 835 1090 547 1052 1199 960 1192 841 1025 29 131 1291 1341 182 671 663 609 1177 905 86 907 55 693 1249 59 926 541 1245 1301 57 687 999 92 175 747 788 741 978 139 481 1362 741 419 1153 454 670 969 820 463 879 1075 783 304 1273 773 851 1088 1016 1267 803 589 122 357 5 106 396 98 1099 1152 176 960 1264 8 321 303 1201 832 151 877 977 178 1339 749 358 1192 111 1141 512 590 827 363 1232 685 933 975 1222 850 1348 1236 554 658 115 1337 1016 977 269 62 1086 291 29 99 683 824 1240 100 1 573 1357 149 364 790 536 40 1246 939 263 1161 462 1373 974 712 791 515 1126 370 1245 1052 856 657 1 1292 437 380 315 988 939 1068 618 362 407 1176 362 1206 27 1113 1065 1166 1193 942 637 443 1053 44 1366 200 680 450 636 1271 457 687 1327 1302 888 695 176 790 916 693 444 289 410 1291 1030 155 801 1129 478 1123 424 91 1057 1059 535 142 490 234 982 220 368 385 1203 854 63 50 454 440 1283 737 210 832 75 1045 1110 1326 1056 589 177 161 96 422 118 1352 1113 1295 1146 587 1330 1094 1356 575 724 90 196 766 481 657 79 219 548 392 157 120 678 672 1326 17 1065 704 583 52 589 1378 365 321 1305 463 668 1323 1331 1036 572 278 753 328 1046 1197 846 724 1170 1153 1154 980 614 335 1072 1221 810 129 521 227 723 1043 407 990 1030 239 814 1034 1287 546 759 1327 1140 1142 442 1135 656 1182 744 240 186 1024 274 1185 1226 744 1154 338 24 216 789 285 638 631 1125 945 1025 226 1026 138 1308 504 102 91 619 1186 891 259 982 336 1245 1280 657 243 417 1336 1281 222 95 1010 768 534 778 1033 876 1309 1289 519 1248 1199 39 169 248 207 416 1377 312 1261 96 1143 1289 709 211 1099 904 389 69 1126 784 662 279 94 1318 856 845 670 791 528 629 689 782 574 13 1152 393 1118 53 750 932 827 131 116 248 505 1059 300 91 1309 373 530 1216 310 652 75 1335 1221 273 285 404 511 417 95 443 1134 253 399 115 517 269 1307 1287 1337 875 536 985 692 252 552 1 1280 1043 1066 123 233 1351 858 216 307 1083 293 866 441 1287 633 615 1197 1365 1006 1259 1230 281 718 875 26 770 929 626 765 1132 1086 139 567 1171 766

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值