• BZOJ_4800_[Ceoi2015]Ice Hockey World Championship_双指针


    BZOJ_4800_[Ceoi2015]Ice Hockey World Championship_双指针

    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

    把序列分成两半,分别搜出所有状态。然后排个序双指针解决。
     
    代码:
    #include <cstdio>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    typedef unsigned long long ll;
    int n,mid;
    ll w[50],a[2000050],b[2000050],m;
    int la,lb;
    void dfs1(int dep,ll sum) {
    	if(dep==mid) {
    		a[++la]=sum; return ;
    	}
    	if(w[dep+1]+sum<=m) dfs1(dep+1,sum+w[dep+1]);
    	dfs1(dep+1,sum);
    }
    void dfs2(int dep,ll sum) {
    	if(dep==n) {
    		b[++lb]=sum; return ;
    	}
    	if(w[dep+1]+sum<=m) dfs2(dep+1,sum+w[dep+1]);
    	dfs2(dep+1,sum);
    }
    int main() {
    	//freopen("shopping.in","r",stdin);
    	//freopen("shopping.out","w",stdout);
    	scanf("%d%llu",&n,&m);
    	int i;
    	for(i=1;i<=n;i++) {
    		scanf("%llu",&w[i]);
    	}
    	if(n==1) {
    		printf("%d
    ",1+(w[1]<=m)); return 0;
    	}
    	mid=(n+1)>>1;
    	dfs1(0,0);
    	dfs2(mid,0);
    	int j=lb;
    	sort(a+1,a+la+1); sort(b+1,b+lb+1);
    	ll ans=0;
    	for(i=1;i<=la;i++) {
    		while(j&&b[j]+a[i]>m) j--;
    		if(j==0) break;
    		ans+=j;
    	}
    	printf("%llu
    ",ans);
    }
    

     

  • 相关阅读:
    一元多项式乘法
    将博客搬至CSDN
    Tomcat的几种部署方式
    Visual Studio 2012以后无法保存只读文件的问题
    WPF中的Generic.xaml, theme以及custom control
    WPF的页面导航
    WPF MVVM系列文章
    tomcat中同时部署两个项目的问题
    Windows多线程系列
    XML DTD和XML Schema
  • 原文地址:https://www.cnblogs.com/suika/p/9092734.html
Copyright © 2020-2023  润新知