历届东北赛补题

13th - B : Balanced Diet

题目大意
要求你选糖果,首先给定m,n代表糖果最大可能种类数和给定的糖果总数,之后给定 m 个值(l1, l2, … lm),代表决定选某一种糖果时至少拿多少个,(可以不选),之后给定 n 个 ai 与 bi,代表每个糖果的价值与所属种类,要求使 S/C 最大 S代表拿取糖果的价值总和,C代表拿的糖果里,出现的最多的种类的糖果个数。
解题思路
首先我们先将每种糖果的取数下限排序,由于当最大值确定时,分母就确定了,为了使总值最大,其他种类的糖果就可以在不超过最大值的情况下尽可能的取最多,所以枚举C,之后只需要遍历每一种类,只要可以拿,就将该种类的糖果尽可能的往里装(最大价值优先),那么就可以得到每一种C时的最优解,比较这些值取最优即可。为了不超时,需要对其优化,不能简单遍历。

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<stack>
using namespace std;
typedef unsigned long long ll;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int N = 1e5 + 100;
const int M = 1e6 + 10;
vector<int> G[N];
int used[N];//用于存储每类糖果已经有多少个被加进去了
int main(){
    std::ios::sync_with_stdio(false);//关闭同步,防止因输入超时
    int t;
    cin >> t;
    while(t--){
        int n, m;
        cin >> n >> m;
        for (int i = 0; i <= m;i++){
            G[i].clear();
            used[i] = 0;
        }
            vector<PII> L;
        for (int i = 1; i <= m;i++){
            int l;
            cin >> l;
            L.push_back({l, i});
        }
        for (int i = 1; i <= n;i++){
            int a, b;
            cin >> a >> b;
            G[b].push_back(a);
        }
        sort(L.begin(), L.end());
        for (int i = 1; i <= m;i++){
            sort(G[i].begin(), G[i].end());
            reverse(G[i].begin(), G[i].end());
        }
        ll ansS = 0, ansC = 1;
        ll S = 0, C = 1;
        ll nowS = 0, nowC = 1;
        //因为C每一次自增一,所以已经符合条件的只需要再加一个值即可,用一个标记存储,已经加入的所有值
        ll vis = 0;//由于 li 排列好了,所以不需要每次遍历,每次C增加只需从不匹配的那个往后找就好
        vector<int> p;
        for (int i = 1; i <= n;i++){
            for (vis; vis < L.size();vis++){
                int tot = L[vis].first;
                if(tot<=i){
                    p.push_back(L[vis].second);
                    //存储符合条件的种类
                    if(G[L[vis].second].size() >= i - 1){
                        for (int j = 0; j < i - 1;j++){
                            nowS += 1ll*G[L[vis].second][j];
                        }
                        used[L[vis].second] = i - 1;
                        //把该种类之前的加进去
                    }
                    else{
                        p.pop_back();//个数不满足弹出
                    }
                }
                else{
                    break;
                }
            }
            for (int k = 0; k < p.size();k++){
                int tot1 = p[k];
                if(used[tot1]<G[tot1].size()){
                    used[tot1]++;
                    nowS +=1ll*G[tot1][used[tot1] - 1];
                }
                //若该类还有糖剩余,就往标记里加入
                else{
                    if(k==p.size() - 1){
                        p.pop_back();
                    }
                    else{
                        p[k] = p[p.size() - 1];
                        k--;
                        p.pop_back();
                    }
                    //没有剩余就把这个种类弹出去,防止不必要的遍历
                }
            }
            if(ansS*i>ansC*nowS){
                continue;
            }
            else{
                ansS = nowS;
                ansC = i;
            }//找最优解
        }
        int ggccdd = __gcd(ansS, ansC);
        ansS /= ggccdd;
        ansC /= ggccdd;
        cout << ansS << '/' << ansC << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值