CF161BDiscounts

Posted wyxdrqc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF161BDiscounts相关的知识,希望对你有一定的参考价值。

CF161B

题目大意;要购买\(n\)件物品,有\(A\)\(B\)两种类型,要求分成\(k\)组,其中如果其中一组含有\(A\)类物品,那么这一组最便宜的一件物品就会半价

怎么分组最小化代价?

我们应该尽量优惠的幅度尽量大

对于一个\(A\)类物品,假设他的价格为\(w\),那么我们绝对不会选择价值比它更小的,因为这样会让我们优惠的代价变小

我们选择贵的又对优惠的价格没有影响,所以

我们能够选择一个比较优的分组方案

先按照价格排序

把最贵的前\(k\)个A(不足\(k\)个就全部)分成一组

然后如果不够组数,就把剩下的尽量补全\(k\)组,然后把每个\(A\)类塞到小于他的最大的\(A\)的那组,如果不存在这样的\(A\),就塞到最后一组

来保证优惠价格的最大化

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#define LL long long
#define pii pair<int,int>
#define mk make_pair
#define fi first
#define se second
using namespace std;
const int N = 2e5 + 3;
inline int read()
    int v = 0,c = 1;char ch = getchar();
    while(!isdigit(ch))
        if(ch == '-') c = -1;
        ch = getchar();
    
    while(isdigit(ch))
        v = v * 10 + ch - 48;
        ch = getchar();
    
    return v * c;

struct node
    int ti;
    int ci; 
    int id;
a[N];
bool book[N],used[N];
vector <int> G[N];
int n,k;
double ans;
inline bool cmp(node x,node y)
    return x.ci > y.ci;

inline bool cmpp(node x,node y)
    return x.id < y.id; 

int main()
    int sum = 0,cnt;
    n = read(),k = read();
    for(int i = 1;i <= n;++i)
        a[i].ci = read(),a[i].ti = read(),sum += (a[i].ti == 1);
        a[i].id = i;
    
    sort(a + 1,a + n + 1,cmp);
    int need = max(0,k - sum),now = 1;
    for(int i = 1;i <= n;++i)
        if(a[i].ti == 1)
            book[now] = 1;
            if(now < k) G[now++].push_back(a[i].id);
            else G[now].push_back(a[i].id);
        
        else
            if(need && now < k) G[now++].push_back(a[i].id),need--;
            else G[now].push_back(a[i].id);
        
    
    sort(a + 1,a + n + 1,cmpp);
    for(int i = 1;i <= now;++i)
        for(int j = 0;j < (int)G[i].size();++j)
            if(j == G[i].size() - 1 && book[i]) ans += (double)a[G[i][j]].ci * 0.5;
            else ans += a[G[i][j]].ci;
        
    
    printf("%.1lf\n",ans);
    for(int i = 1;i <= now;++i)
        printf("%d ",G[i].size());
        for(int j = 0;j < (int)G[i].size();++j) printf("%d ",G[i][j]);
        putchar('\n');
    
    return 0;


以上是关于CF161BDiscounts的主要内容,如果未能解决你的问题,请参考以下文章

CF161D Distance in Tree

CF161D Distance in Tree |点分治

XSY2411CF161DDistance in Tree

JavaScript máscarasparaformulários

关于盐值的理解

RegOpenKeyEx 返回错误 161