zoukankan      html  css  js  c++  java
  • Lotus and Characters (stronger)

    题意:

    有n类物品,第i种物品权值为$val(i)$,有$cnt(i)$个,现在你可以选出一些物品排成一个序列(假设有m个),

    记第i个物品种类为$x_i$,最大化$sum_{i=1}^m{i * val(x_i)}$

    解法:

    只要将物品分为两类即可。

    对于$val(i) ge 0$的直接从小到大排列插入序列末端即可,然后在序列首端插入物品,

    记当前后缀和为$suffixsum$。

    接下来从大到小插入$val(i)<0$的物品,每插入一个会产生$suffixsum+val(i)$的答案贡献,并且影响$suffixsum$

    贪心正确性显然,接下来考虑加速插入物品的过程,

    一次性插入t个i类物品不更新$suffixsum$对答案的贡献为$t*suffixsum + frac{t*(t+1)}{2}*val(i)$,

    且有$t le frac{-suffixsum}{val(i)}$。

    从而$O(nlogn)$解决此问题。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 
     6 #define N 1010
     7 #define LL long long
     8 
     9 using namespace std;
    10 
    11 int val[N],cnt[N],a[N];
    12 
    13 bool cmp(int a,int b)
    14 {
    15     return val[a]<val[b];
    16 }
    17 
    18 LL S(LL n)
    19 {
    20     return n*(n+1LL)/2LL;
    21 }
    22 
    23 int main()
    24 {
    25     int T,n;
    26     scanf("%d",&T);
    27     while(T--)
    28     {
    29         scanf("%d",&n);
    30         for(int i=1;i<=n;i++)
    31             scanf("%d%d",&val[i],&cnt[i]),a[i]=i;
    32         sort(a+1,a+n+1,cmp);
    33         int sum=0;
    34         LL ans=0,suffix_sum=0;
    35         for(int i=1;i<=n;i++)
    36         {
    37             if(val[a[i]]<0) continue;
    38             sum += cnt[a[i]];
    39             ans += (S(sum)-S(sum-cnt[a[i]])+0LL) * (LL)val[a[i]];
    40             suffix_sum += cnt[a[i]] * (LL)val[a[i]];
    41         }
    42         for(int i=n;suffix_sum>0 && i>=1;i--)
    43         {
    44             if(val[a[i]]>=0) continue;
    45             LL tmp = (-suffix_sum)/val[a[i]];
    46             tmp = min(tmp, (LL)cnt[a[i]]);
    47             ans += tmp*suffix_sum + S(tmp)*val[a[i]];
    48             suffix_sum += tmp*val[a[i]];
    49         }
    50         cout << ans << endl;
    51     }
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    算法-经典趣题-寻找假银币
    一天一个 Linux 命令(3):cat 命令
    算法-经典趣题-青蛙过河
    常用数据库有哪些?
    SpringBoot2.0入门教程(一) 快速入门,项目构建HelloWorld示例
    一天一个 Linux 命令(2):ls 命令
    算法-经典趣题-爱因斯坦阶梯问题
    一天一个 Linux 命令(1):vim 命令
    什么是开发环境、测试环境、UAT环境、仿真环境、生产环境?
    算法-经典趣题-渔夫捕鱼
  • 原文地址:https://www.cnblogs.com/lawyer/p/6568411.html
Copyright © 2011-2022 走看看