zoukankan      html  css  js  c++  java
  • Codeforces 808 E. Selling Souvenirs(三分)

    E. Selling Souvenirs

    题意:
    n件物品,有重量和价值,重量只有三种1,2,3。问取不超过m重量的物品的价值总和最大是多少。(n<=1e5,w<=3e5)
    思路:
    n*w很大,常规01背包不能直接做。考虑到物品重量不超过3,可以按重量分类物品。枚举重量3的物品取的件数,可以发现如果重量2的物品取得多则重量1的物品就得取得少,反之亦然。因此所取重量1,2的物品的价值和与重量2物品取的件数应该满足一个上凸函数的关系,即有一个极值点,那个点就是当前枚举下的1,2物品最大价值和。因此枚举重量3的物品件数,三分重量2的物品件数可以解决这个问题。
    代码:

    #include<bits/stdc++.h>
    #define dd(x) cout<<#x<<" = "<<x<<" "
    #define de(x) cout<<#x<<" = "<<x<<"
    "
    #define sz(x) int(x.size())
    #define All(x) x.begin(),x.end()
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef pair<int,int> P;
    typedef priority_queue<int> BQ;
    typedef priority_queue<int,vector<int>,greater<int> > SQ;
    const int maxn=1e5+10,mod=1e9+7,INF=0x3f3f3f3f;
    vector<int> v[5];
    ll sum[5][maxn]; 
    ll f(int w,int n)
    {
    	return sum[2][n]+sum[1][min(sz(v[1]),w-2*n)];
    }
    int main()
    {
    	int n,m;
    	cin>>n>>m;
    	for (int i=0;i<n;++i)
    	{
    		int w,c;
    		scanf("%d%d",&w,&c);
    		v[w].pb(c);
    	}
    	for (int i=1;i<=3;++i)
    	{
    		sort(All(v[i]),[&](int a,int b){return a>b;});
    		for (int j=1;j<=sz(v[i]);++j)
    			sum[i][j]=sum[i][j-1]+v[i][j-1];
    	}
    	ll ans=0;
    	for (int i=0;i<=sz(v[3])&&3*i<=m;++i)
    	{
    		int rest=m-3*i,l=0,r=min(sz(v[2]),rest/2);
    		ans=max(ans,max(f(rest,l),f(rest,r))+sum[3][i]);
    		while (r-l>1)
    		{
    			int lmid=(l+r)>>1,rmid=(lmid+r)>>1;
    			if (f(rest,lmid)<f(rest,rmid))
    				l=lmid;
    			else
    				r=rmid;
    		}
    		ans=max(ans,max(f(rest,l),f(rest,r))+sum[3][i]);
    	}
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    深入学习Make命令和Makefile(上)
    make命令
    ubuntu 重启网络方法--通过杀死进程重启网络
    悟空遥控器 --- 手机投屏到电视 播放视频
    组织结构图 --- 商务
    软件和数据库
    因果图---鱼骨图
    流程图 --- BPMN规范简介
    异次元软件
    Free Download Manager (FDM) 中文版
  • 原文地址:https://www.cnblogs.com/orangee/p/10328414.html
Copyright © 2011-2022 走看看