• HDU 4546 比赛难度


    比赛难度

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 46    Accepted Submission(s): 6


    Problem Description
      最近,小明出了一些ACM编程题,决定在HDOJ举行一场公开赛。
      假设题目的数量一共是n道,这些题目的难度被评级为一个不超过1000的非负整数,并且一场比赛至少需要一个题,而这场比赛的难度,就是所有题目的难度之和,同时,我们认为一场比赛与本场题目的顺序无关,而且题目也不会重复。
      显而易见,很容易得到如下信息:
      假设比赛只用1个题目,有n种方案;
      假设比赛使用2个题目,有(n-1)*n/2种方案;
      假设比赛使用3个题目,有(n-2)*(n-1)*n/6种方案;
      ............
      假设比赛使用全部的n个题目,此时方案只有1种。
      
      经过简单估算,小明发现总方案数几乎是一个天文数字!
      为了简化问题,现在小明只想知道在所有的方案里面第m小的方案,它的比赛难度是多少呢?
     
    Input
    输入数据的第一行为一个整数T(1 <= T <= 20),表示有T组测试数据。
    每组测试数据第一行为两个整数n, m(0 < n, m <= 10000),表示现在有n个题目,现在要求第m小的方案的比赛难度。接下来第二行有n个数字,分别表示这n个题目的难度值。
     
    Output
    对于每组测试数据,输出一行"Case #c: ans"(不包含引号),ans 表示要求的第m小的比赛难度,输入数据保证存在第m小的方案,具体参见样例。
     
    Sample Input
    2 5 6 1 1 1 1 1 5 25 1 2 3 4 5
     
    Sample Output
    Case #1: 2 Case #2: 11
     
    Source
     
    Recommend
    liuyiding
     
     
     
     
    我的做法就是不断合并两个有序的数组,维护一个递增的数组。
    先把a数组从小到大排序。
     
    比如前i-1 个数组合产生一个有序的数组
    b[now][1]  、 b[now][2]、b[now][3]、··········b[now][b[now][0]]
    所以b[now][0]存的是数组的个数
     
    然后a[i]加入进来。含有a[i]的产生一个新的序列:a[i]、a[i]+b[now][1]  、 a[i]+b[now][2]、a[i]+b[now][3]、··········a[i]+b[now][b[now][0]]
     
    将两个有序的数列合并,就得到前i个数组合产生的有序数组。
    然后不断递推下去。
     
    这个数组的大小不要大于m,大于m部分就不需要了
     
    还有如果数组的大小大于m了,就是满了,而且当前的a[i]没有进去,说明后面的也进不去了,直接break;
     
     
    感觉我的做法复杂度比较大==55555555
     
    金山西山居比赛的时候竟然抢到了这题的FB,我都没有想到。。。zzzzzzzz 貌似这样的不是正解。
     
     
    //============================================================================
    // Name        : B.cpp
    // Author      : 
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    
    #include <iostream>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <vector>
    #include <math.h>
    #include <string>
    #include <stdio.h>
    #include <math.h>
    using namespace std;
    const int MAXN=10010;
    int a[MAXN];
    int b[2][MAXN];
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int n,m;
        int iCase=0;
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            iCase++;
            for(int i=0;i<n;i++)
            {
                scanf("%d",&a[i]);
            }
            sort(a,a+n);
            int now=0;
            b[now][0]=1;
            b[now][1]=a[0];
            for(int i=1;i<n;i++)
            {
                int t1=1,t2=1;
                bool ff=false;
                b[now^1][0]=0;
                while(t1<=b[now][0] && t2<=b[now][0] && b[now^1][0]<=m)
                {
                    if(!ff && a[i]<=min(b[now][t1],b[now][t2]+a[i]))
                    {
                        b[now^1][++b[now^1][0]]=a[i];
                        ff=true;
                        continue;
                    }
                    if(b[now][t1]<b[now][t2]+a[i])
                        b[now^1][++b[now^1][0]]=b[now][t1++];
                    else
                        b[now^1][++b[now^1][0]]=b[now][t2++]+a[i];
    
                }
                while(t1<=b[now][0] && b[now^1][0]<=m)
                {
                    if(!ff && a[i]<=b[now][t1])
                    {
                        b[now^1][++b[now^1][0]]=a[i];
                        ff=true;
                        continue;
                    }
                    b[now^1][++b[now^1][0]]=b[now][t1++];
                }
                while(t2<=b[now][0] && b[now^1][0]<=m)
                {
                    if(!ff && a[i]<=b[now][t2]+a[i])
                    {
                        b[now^1][++b[now^1][0]]=a[i];
                        ff=true;
                        continue;
                    }
                    b[now^1][++b[now^1][0]]=b[now][t2++]+a[i];
                }
                if(!ff && b[now^1][0]<=m)
                {
                    b[now^1][++b[now^1][0]]=a[i];
                    ff=true;
                }
    
                now^=1;
                if(!ff)break;
    
            }
            printf("Case #%d: %d\n",iCase,b[now][m]);
        }
        return 0;
    }
     
     
     
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    北亚一例服务器硬盘故障的数据恢复案例研究
    Syabse数据库无法启动的解决方案
    raid5 阵列硬盘离线数据恢复成功案例
    MSSQL 2000 错误823恢复案例
    服务器数据恢复案例
    虚拟机数据丢失的数据恢复过程和数据恢复方法
    数据库打开时报错该如何解决
    误删除导致文件系统中的邮件丢失的数据恢复过程
    第16月第25天 tableView设置UITableViewStyleGrouped顶部有空余高度
    第16月第24天 find iconv sublime utf-8
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3084425.html
Copyright © 2020-2023  润新知