zoukankan      html  css  js  c++  java
  • 4800: [Ceoi2015]Ice Hockey World Championship(折半搜索)

    4800: [Ceoi2015]Ice Hockey World Championship

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 622  Solved: 311
    [Submit][Status][Discuss]

    Description

    有n个物品,m块钱,给定每个物品的价格,求买物品的方案数。
     

     

    Input

    第一行两个数n,m代表物品数量及钱数
    第二行n个数,代表每个物品的价格
    n<=40,m<=10^18
     

     

    Output

    一行一个数表示购买的方案数
    (想怎么买就怎么买,当然不买也算一种)
     

     

    Sample Input

    5 1000
    100 1500 500 500 1000

    Sample Output

    8

    HINT

     

    Source

    #include<bits/stdc++.h>
    
    #define N 45
    #define M 1000007
    #define ll long long
    
    using namespace std;
    ll n,m,ans,cnt,mx,flag;
    ll val[N],f[N][M];
    
    inline ll read()
     {
         ll x=0,f=1;char c=getchar();
         while(c>'9'||c<'0'){if(x=='-')f=-1;c=getchar();}
         while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
         return x*f;
     }
    
    void dfs(int k,ll sum)
    {
        if(sum>m) return;
        if(k==n)
        {
            ans++;return;
        }
        dfs(k+1,sum);
        dfs(k+1,sum+val[k+1]);
    }
    
    void dp()
    {
        f[0][m]=1;
        for(int i=1;i<=n;i++) for(int j=0;j<=m;j++)
        {
            f[i][j]+=f[i-1][j]+f[i-1][j+val[i]];
        }
        for(int i=0;i<=m;i++) ans+=f[n][i];
    }
    
    int main()
    {
        //freopen("ly.in","r",stdin);
        n=read();m=read();
        for(int i=1;i<=n;i++) val[i]=read();
        if(m<=1e6) dp();
        else dfs(0,0);
        printf("%lld
    ",ans);
        return 0;
    } 
    80暴力 dfs+dp
    /*
    折半搜索 
    */
    #include<bits/stdc++.h>
    
    #define ll long long
    #define N 55
    
    using namespace std;
    ll n,m,mid,cnta,cntb,ans;
    ll w[N],suma[1<<21],sumb[1<<21];
    
    inline ll read()
     {
         ll x=0,f=1;char c=getchar();
         while(c>'9'||c<'0'){if(x=='-')f=-1;c=getchar();}
         while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
         return x*f;
     }
    
    inline void dfs(int l,int r,ll sum,ll a[],ll &cnt)
    {
        if(sum>m)return;
        if(l>r)
        {
            a[++cnt]=sum;return;
        }
        dfs(l+1,r,sum+w[l],a,cnt);
        dfs(l+1,r,sum,a,cnt);
    }
    
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++)w[i]=read();;
        mid=n/2;
        dfs(1,mid,0,suma,cnta);
        dfs(mid+1,n,0,sumb,cntb);
        sort(suma+1,suma+1+cnta);
        for(int i=1; i<=cntb; i++)
            ans+=upper_bound(suma+1,suma+1+cnta,m-sumb[i])-suma-1;
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    JSON操作技巧
    我的前端学习历程(转)
    sql指南网址
    using 和try/catch区别和注意点
    【转】StringBuffer的用法与string的区别
    【转】比较page、request、session、application的使用范围
    【转】StringBuilder用法
    【转】.Net高级技术——IDisposable
    【转】.NET快速查找某个类所在的命名空间
    【转】VS2010安装包制作
  • 原文地址:https://www.cnblogs.com/L-Memory/p/9888040.html
Copyright © 2011-2022 走看看