CCPC-Wannafly Winter Camp Day1 (Div2, onsite) J 夺宝奇兵

分类:枚举 贪心
传送门:夺宝奇兵https://www.zhixincode.com/contest/1/problem/J?problem_id=21
类似题目:codeforce#round div2 C.Election

##思路##

1.为什么要用vector,而不直接用数组呢?
因为每个人的每个物品,他的价值不一样,不可以随便拿来++ –
我们还有根据这个人的物品大小,从小到大的拿,用vector便于排序
2.那么什么时候要拿呢?
我们要拿走 比我们手中的个数多的人的物品,
如果还不够的话,剩余数量从全局从小到大的拿
(以上1.2. 就是在贪心的拿物品)
3.可是我们怎么知道最优的结果是什么???
那我们就枚举,我手中有i个物品时的情况。
这样,我们就可以得到我手中 拿着各种个数时,最优的情况;这些情况下最优的就是全局最优的了

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1005;
struct node
{
    ll id,cost;
};
int cmp(node a ,node b)
{
    return a.cost<b.cost;
}
vector<node>all;
vector<node>man[maxn];
int vis[maxn];
int n,m;
int main()
{
    cin>>n>>m;
    int a,b;
    for(int i=0;i<m;i++)
    {
        cin>>a>>b;
        all.push_back({i,a});
        man[b].push_back({i,a});
    }
    sort(all.begin(),all.end(),cmp);
    for(int i=1;i<=n;i++)
    {
        sort(man[i].begin(),man[i].end(),cmp);
    }
    ll maxx=1e15;
    //枚举所有情况
    for(ll k=1;k<=m;k++)
    {
        ll ans=0,num=0;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)
        {
            if(man[i].size()>=k)
            {
                for(int j=0;j<=man[i].size()-k;j++)
                {
                    ans+=man[i][j].cost;
                    num++;
                    vis[man[i][j].id]=1;
                }
            }
        }
        for(ll i=0;i<all.size() && num<k ;i++)
        {
            if(!vis[all[i].id])
            {
                ans+=all[i].cost;
                num++;
            }
        }
        maxx=min(maxx,ans);
    }
    cout<<maxx<<endl;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值