zoukankan      html  css  js  c++  java
  • 大奖赛

    大奖赛

    champion.c/cpp/pas

    (1s/256M)

    【题目描述】

    Lancelot市近期要举办大奖赛!住在市里的市民都十分兴奋,Morgan也不例外。他查了一下比赛的信息,发现比赛一共由N场,并且每一场门票价格可能会不相等。Morgan留给比赛的预算是K元;他想知道,一共有多少种买票的方案,使得门票之和不超过K呢

    【输入格式champion.in

    第一行两个整数NK代表比赛的场数和自己的预算。

    第二行N个整数Ai代表每场比赛的门票价格。

    【输出格式champion.out

    一行一个整数,代表买票的总方案

    【样例输入】

    5 1000

    2000 100 500 500 1000

    【样例输出】

    8

    【数据范围与约束】

    对于30%的数据,N<=10.搜索

    对于60%的数据,K<=10,000.背包

    对于100%的数据,1<=N<=40, 0<K,Ai<=1,000,000,000.折半搜索

    折半搜索的目的就是降低时间复杂度。

      把N分成两半,分开搜索,单独的时间复杂度大约是2^20 左右。

      然后把 A组的排个序, 每得到一个B组中的元素,就看看能和A中元素组成几个新的。

    背包写法

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue> 
    #include<cstring>
    using namespace std;
    const int N=10000;
    int a[50];
    int f[20000];
    int n,k;
    int main()
    {
        freopen("champion.in","r",stdin);
        freopen("champion.out","w",stdout);
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)    scanf("%d",&a[i]);
        f[0]=1;
        
        for(int i=1;i<=n;i++)
        for(int j=k;j>=a[i];j--)
            f[j]+=f[j-a[i]];
        long long ans=0;
        for(int i=0;i<=k;i++)    
            ans+=f[i];
        cout<<ans;
        return 0;
    }

     折半

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int N=45;
    const int S=(1<<20)+11;
    int n,k;
    int a[N],pa;
    int b[N],pb;
    int c[S],cnt;
    long long ans=0;
    void dfs(int x,int y)
    {
        if(y>k) return ;
        if(x==pa)
        {
            c[cnt++]=y;
            return ;
        }
        dfs(x+1,y);dfs(x+1,y+a[x]);
    }
    void dfs2(int x,int y)
    {
        if(y>k) return ;
        if(x==pb)
        {
            ans+=upper_bound(c,c+cnt,k-y)-c;
            return ;
        }    
        dfs2(x+1,y);dfs2(x+1,y+b[x]);
    }
    int main()
    {
        freopen("champion.in", "r", stdin);
        freopen("champion.out", "w", stdout);
        scanf("%d%d",&n,&k);
        for(int i=0;i<n;i++)    
            scanf("%d",&a[i]);
            
        pa=n/2;pb=n-pa;
        for(int i=pa;i<n;i++)
            b[i-pa]=a[i];
        
        dfs(0,0);
        sort(c,c+cnt);
        
        dfs2(0,0);
        cout<<ans<<endl;
        return 0;
    } 
  • 相关阅读:
    [转帖]一些理念,一份感动,一段友谊。或许在短暂的一生中就弥足珍贵了。
    浏览器屏蔽双击选中文字
    RBAC: 基于角色的访问控制(Role-Based Access Control)
    关于ehcache配置中timeToLiveSeconds和timeToIdleSeconds的区别
    拓展jQuery的方法
    用HashSet存储不重复的对象
    spring task 实现定时执行(补充:解决定时任务执行2次问题)
    CronExpression
    java使用POI实现excel文件的读取,兼容后缀名xls和xlsx
    jquery的原理机制
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7715831.html
Copyright © 2011-2022 走看看