首页 > 其他分享 >【题解】CF808E Selling Souvenirs

【题解】CF808E Selling Souvenirs

时间:2023-01-04 21:57:16浏览次数:38  
标签:Selling int 题解 ll ws ans 物品 CF808E size

题意

多重背包,但数据范围很大并且体积小于等于三。

思路

乱搞。

很自然地考虑将物品按照体积分成三类。

显然对于同一类的物品从最大开始取最优,那么有一个贪心的想法。

直接枚举其中两类物品的数量,可以得到一个流浪者暴力。

令 \(f(a, b)\) 为取 \(a\) 个第一类物品,\(b\) 个第二类物品的最大收益,那么 \(f\) 是关于 \(a\) 单峰的。

那么只需要枚举第三类物品的数量,然后三分求最大值即可。

注意可能会有平台,随便搞一下。

代码

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

typedef long long ll;

const int maxn = 1e5 + 5;

int n, m;
int w[maxn], c[maxn];
vector<ll> ws[4];

bool cmp(int a, int b) { return (a > b); }

ll calc(ll x, ll y)
{
	//printf("%d %d\n",x,y/2);
	if (y % 2) x++;
	if (ws[1].size() == 0 || x == 0) x = 0;
	else x = ws[1][min(x - 1, (ll)ws[1].size() - 1)];
	if (ws[2].size() == 0 || y < 2) y = 0;
	else y = ws[2][min(y / 2 - 1, (ll)ws[2].size() - 1)];
	return x + y;
}

int main()
{
    ll ans = 0;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d%d", &c[i], &w[i]);
        ws[c[i]].push_back(w[i]);
    }
    for (int i = 1; i <= 3; i++)
    {
        sort(ws[i].begin(), ws[i].end(), cmp);
        for (int j = 1; j < ws[i].size(); j++) ws[i][j] += ws[i][j - 1];
    }
    for (int i = 0; i <= min(m / 3, (int)ws[3].size()); i++)
    {
        int rem = m - 3 * i;
        int l = 0, r = min(rem, (int)ws[1].size());
        if (ws[1].size() + 2 * ws[2].size() <= rem)
        {
            ans = max(ans, (i ? ws[3][i - 1] : 0) + calc(ws[1].size(), 2 * ws[2].size()));
            continue;
        }
        while (l < r)
        {
            int mid1 = l + (r - l) / 3, mid2 = r - (r - l) / 3;
            ll val1 = calc(mid1, rem - mid1), val2 = calc(mid2, rem - mid2);
            // printf("debug %d %d\n", val1, val2);
            if (val1 > val2) r = mid2 - 1;
            else l = mid1 + 1;
        }
        // printf("debug %d\n", l);
        ans = max(ans, (i ? ws[3][i - 1] : 0) + calc(l, rem - l));
    }
    printf("%lld\n", ans);
    return 0;
}

标签:Selling,int,题解,ll,ws,ans,物品,CF808E,size
From: https://www.cnblogs.com/lingspace/p/cf808e.html

相关文章

  • 【题解】P5305 [GXOI/GZOI2019]旧词
    题面很清楚,不概括题意了。思路树剖。\(k=1\)的情况是P4211[LNOI2014]LCA具体来说,只需要\(\forall1\leqi\leqx\),将\(1\)到\(i\)的路径上每一个结点权值......
  • 题解 校内考20230104 T2 旗木双翼
    题目描述菲菲和牛牛在一块\(n\)行\(m\)列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手。棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束。落子......
  • LOJ 数列分块入门 9 题解题报告
    LOJ数列分块入门9题解题报告\(\text{ByDaiRuiChen007}\)I.数列分块入门1题目大意\(\text{Link}\)维护一个长度为\(n\)的序列,支持区间加,单点查值思路分析简......
  • IntelliJ IDEA常见问题解决办法汇总
     mac上idea升级到2020.2.2后,发现versioncontrol中的localchanges不见了!解决办法:View—>ToolWIndows—>Commit【点击下,就会提示要把这个Commit放在IDEA面板那个位置,选择......
  • git 不区分大小写问题解决
    使用vscode   更改vue文件为大驼峰的方式 发现本地代码和提交时的代码名称不同是因为git不区分大小写这时我们需要找到代码存放位置 鼠标右键  GitBashHer......
  • 异地多活回环同步问题解决方案
    1.异地多活:一般为两地三中心或者三地五中心,这样设计是为了在发生单点故障或网络分区时,集群能继续提供服务。两地三中心可以容忍机房级别灾难,三地五中心可以容忍城市级别灾......
  • Codeforces Hello 2023 CF 1779 A~F 题解
    点我看题A.HallofFame先把不用操作就合法的情况判掉。然后发现交换LL,RR,RL都是没用的,只有交换LR是有用的,这样可以照亮相邻的两个位置。所以我们就是要找到一个位置i,......
  • Codeforces Hello 2023 CF 1779 A~F 题解
    点我看题A.HallofFame先把不用操作就合法的情况判掉。然后发现交换LL,RR,RL都是没用的,只有交换LR是有用的,这样可以照亮相邻的两个位置。所以我们就是要找到一个位置i,......
  • 题解 P3526 [POI2011]OKR-Periodicity
    P3526[POI2011]OKR-Periodicitynb题。先说一下这题的入手点。不妨假设一个字符串一定存在一个短周期(约定周期\(p\)满足\(2p\leq|s|\)的为短周期),假设短周期的长度......
  • 寒假第一次洛谷蓝桥个人赛 题解+补题(下)
    D.灵能传输##神仙结论把前缀和应用到极致,6先考虑三个数a,b,c,进行一次变换也就是a+b,-b,c+b可见三个数之和不变,也就是s[3]不变然后之前的s[1]+b,愿称之为s[2]之前的s......