【牛客网】小咪买东西(二分答案)

题目描述:

在这里插入图片描述在这里插入图片描述在这里插入图片描述

解题思路:

假设小咪只想买3件物品,并且最终买了物品 i , j , k i,j,k i,j,k使得所求的最大值为 m a x max max。则有关系式 v [ i ] + v [ j ] + v [ k ] c [ i ] + c [ j ] + c [ k ] = m a x \frac{v[i]+v[j]+v[k]}{c[i]+c[j]+c[k]}=max c[i]+c[j]+c[k]v[i]+v[j]+v[k]=max成立,也即 v [ i ] + v [ j ] + v [ k ] − m a x ∗ c [ i ] − m a x ∗ c [ j ] − m a x ∗ c [ k ] = 0 v[i]+v[j]+v[k]-max*c[i]-max*c[j]-max*c[k]=0 v[i]+v[j]+v[k]maxc[i]maxc[j]maxc[k]=0成立。假如我们随便猜一个数 x x x去替代" v [ i ] + v [ j ] + v [ k ] − m a x ∗ c [ i ] − m a x ∗ c [ j ] − m a x ∗ c [ k ] v[i]+v[j]+v[k]-max*c[i]-max*c[j]-max*c[k] v[i]+v[j]+v[k]maxc[i]maxc[j]maxc[k]"中的 m a x max max,如果x被我们猜大了则 v [ i ] + v [ j ] + v [ k ] − x ∗ c [ i ] − x ∗ c [ j ] − x ∗ c [ k ] < 0 v[i]+v[j]+v[k]-x*c[i]-x*c[j]-x*c[k]<0 v[i]+v[j]+v[k]xc[i]xc[j]xc[k]<0,若 x x x被猜小了则 v [ i ] + v [ j ] + v [ k ] − x ∗ c [ i ] − x ∗ c [ j ] − x ∗ c [ k ] > 0 v[i]+v[j]+v[k]-x*c[i]-x*c[j]-x*c[k]>0 v[i]+v[j]+v[k]xc[i]xc[j]xc[k]>0。由此,我想到可以将此题转化为二分搜索:在可能的答案区间里猜这个最大值,猜大了就往小了猜,猜小了就往大了猜。直到这个数接近 m a x max max即可。

AC代码:

#include<iostream>
#include<algorithm>
     using namespace std;
     const int maxn=1e4+100;
     int n,k;
     double c[maxn],v[maxn];
     bool check(double x){
     double y[maxn];
     for(int i=1;i<=n;i++){
      y[i]=v[i]-x*c[i];
     }
     sort(y+1,y+n+1);
     double s=0;
     for(int i=n;i>n-k;i--){  //选择前k个最大y[i]累加,如果最大的累加和都小于0则这个数一定猜大了
     s+=y[i];
     }
     return s>=0;    //s>=0则表示猜小了。也即返回true时表示猜小了
     }
     int Bsearch(double l,double r){
     int t=100;      //猜100次就足以让答案满足“精确至整数”的精度。
     while(t--){
     double m=(l+r)/2;
     if(check(m)) l=m;   //猜小了就往大了猜
     else r=m;           //猜大了就往小了猜
     }
     return (int)l;
     }
     int main(){
     int t;
     cin>>t;
     while(t--){
     cin>>n>>k;
     for(int i=1;i<=n;i++){
      cin>>c[i]>>v[i];
     }
     double l=0;
     double r=1e4;      //大致估计答案在0-10000之间
     cout<<Bsearch(l,r)<<endl;
     }
    return 0;
     }


上一篇博客:【leetcode】778. 水位上升的泳池中游泳(dfs+二分答案)

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 C# 的正则表达式来按照学科拆分试卷中的题目、答案和解析。以下是一个示例代码: ```csharp using System; using System.Text.RegularExpressions; class Program { static void Main() { string html = "<html><body><div><h2>数学</h2><p>1. 2+2=4</p><p>答案:A</p><p>解析:略</p><p>2. 3+3=6</p><p>答案:B</p><p>解析:略</p></div><div><h2>语文</h2><p>1. 中国的首都是哪里?</p><p>答案:B</p><p>解析:北京是中国的首都。</p><p>2. 人类的本质是什么?</p><p>答案:C</p><p>解析:略</p></div></body></html>"; // 定义正则表达式 Regex subjectRegex = new Regex(@"<h2>(.*?)<\/h2>"); Regex questionRegex = new Regex(@"<p>(\d+)\.(.*?)<\/p>"); Regex answerRegex = new Regex(@"<p>答案:(.*?)<\/p>"); Regex analysisRegex = new Regex(@"<p>解析:(.*?)<\/p>"); // 匹配学科 MatchCollection subjectMatches = subjectRegex.Matches(html); foreach (Match subjectMatch in subjectMatches) { string subject = subjectMatch.Groups[1].Value; Console.WriteLine("学科:" + subject); // 匹配题目、答案和解析 MatchCollection questionMatches = questionRegex.Matches(subjectMatch.NextMatch().Value); MatchCollection answerMatches = answerRegex.Matches(subjectMatch.NextMatch().Value); MatchCollection analysisMatches = analysisRegex.Matches(subjectMatch.NextMatch().Value); for (int i = 0; i < questionMatches.Count; i++) { string questionNumber = questionMatches[i].Groups[1].Value; string questionContent = questionMatches[i].Groups[2].Value; string answer = answerMatches[i].Groups[1].Value; string analysis = analysisMatches[i].Groups[1].Value; Console.WriteLine("题目" + questionNumber + ":" + questionContent); Console.WriteLine("答案:" + answer); Console.WriteLine("解析:" + analysis); } } } } ``` 在这个示例代码中,我们使用了四个正则表达式来匹配试卷中的内容。首先,我们使用 `subjectRegex` 匹配学科标题;然后,我们使用 `questionRegex` 匹配题目内容和编号;接着,我们使用 `answerRegex` 匹配答案;最后,我们使用 `analysisRegex` 匹配解析。通过遍历匹配结果,我们可以将试卷中的内容拆分成题目、答案和解析,然后按照学科进行分类输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值