4 条题解

  • 3
    @ 2025-11-3 21:04:05
    #include<bits/stdc++.h>//终于懂了,给写个注释
    using namespace std;
    long long a[200100],b[200100];
    int main(){
        int n;
        scanf("%d",&n);
        for(int i = 1; i <= n; i++){
            scanf("%lld",&a[i]);//先把每一轮的价格存入数组a;
        }
        b[n+1] = 1e18;//设极大值防止a[n]大于b[n+1]
        for(int i = n; i >= 1; i--){//从后往前遍历,预处理出b数组,b[i]表示从i到n轮的最低价
            b[i] = min(b[i+1], a[i]);
        }
        long long ans = 0, cost = 0;//cost表示已花费的哈夫币
        for(int i = 1; i <= n; i++){
            if(a[i] == b[i]){//只有当前轮次价格是从i到n轮的最低价再购买
                long long z = (i - cost) / a[i];
                if(z > 0){
                    ans += z;
                    cost = cost + z * a[i];//累计花费的成本
                }
            }
        }
        printf("%lld",ans);//答案!!
        return 0;
    }//抄的学姐代码,给大家发个注释看看能不能更好理解
    
    • @ 2025-11-3 21:06:30

      每次买的都是当前已有哈夫币能买的最低价格的大红,所以这样买出来的数量是最优的

  • 2
    @ 2025-11-2 23:32:07

    为了能购买最大数量的大红,我们肯定要多买价钱低的大红,那我们就去求数组c的最小后缀,也就是说,求从c[n]到c[i]的最小值,假设我们用数组b去存数组c的最小后缀,那b[i]的值就代表从c[n]到c[i]的最小值,之后我们在按照题意去遍历c数组,当b[i]==c[i]时,就是我们的最佳购买时机。那为什么不从c[1]往c[i]去遍历呢?原因就在于后面可能会有比前面更低的价格,在加上如果我们在前几轮不买大红,那我们的钱就会越来越多,所以从c[n]到c[i]才是最佳方案。
    #include<bits/stdc++.h>
    using namespace std;
    long long a[200100],b[200100];
    int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
    scanf("%lld",&a[i]);
    }
    b[n+1]=1e18;
    for(int i=n;i>=1;i--){
    b[i]=min(b[i+1],a[i]);
    }
    long long ans=0,cost=0;
    for(int i=1;i<=n;i++){
    if(a[i]==b[i]){
    long long z=(i-cost)/a[i];
    if(z>0){
    ans+=z;
    cost=cost+z*a[i];
    }
    }
    }
    printf("%lld",ans);
    return 0;
    }

    • 1
      @ 2025-11-3 9:05:47

      /主要思路是找到数组中最小值的最后位置,因为越到后面钱越多,算出能买多少大红(买不了也没关系,说明前边比他大的更买不了), 然后从最小值后面开始再找最小值,重复上面操作,直到最小值为最后一个值为止/

      #include<bits/stdc++.h>

      using namespace std;

      int main()

      {

      ios::sync_with_stdio(false);

      cin.tie(nullptr);

      int n,l=1;

      int count=0;//大红数量

      int money=0;

      cin>>n;

      vector<int>arr(n+1,0);

      for(int i=1;i<=n;i++)

      {

      cin>>arr[i];

      }

      while(l<=n)//不断寻找最小值,直到最小值为最后一个值为止

      {

      int min=1e9,j;

      for(int i=l;i<=n;i++)

      {

      if(arr[i]<=min)

      {

      min=arr[i];

      j=i;//标记最小值的最后位置

      }

      money++;

      }

      money=money-(n-j);//计算到标记位置是的钱

      count+=money/arr[j];//大红数量

      money=money%arr[j];//购买后剩余钱

      l=j+1;//从最小值后面开始再找最小值

      }

      cout<<count;

      }

      • 0
        @ 2025-11-4 19:41:05
        #include <stdio.h>
        #include <stdlib.h>
        #define min(a, b) ((a) < (b) ? (a) : (b))
        long long a[200009], b[200009];
        int main() {
            int n;
            scanf("%d", &n);
            for(int i = 0; i < n; i++)
             {
                scanf("%lld", &a[i]);
            }
            b[n] = 1e18;
            //b[i]表示第i到第n中最低的价格,i=n的时候,第n的价格和自己做比较
            //肯定还是自己,为了防止a[n]>b[n]导致无法取到正常的a[n],我们把
            //b[n]给个很大很大的值
            //现在我们知道b[i+1]的意思是从第i+1到n中最小的值
            //所以b[i]只需要让b[i+1]和a[i]做比较就好
            for(int i = n-1; i >= 0; i--)
             {
                b[i] = min(b[i+1], a[i]);
            }
            long long coins = 0;
            long long totalcost = 0;
            int ans = 0;
            for(int i = 0; i < n; i++)
             {
                coins++;//买不买先把每天的钱领了
                if(totalcost > i + 1)//i从0开始,i+1是总钱数
                 {
                    break;
                }
                if(a[i] == b[i])//很合适的价格,再往后没有比他更便宜的了
                 {
                    long long buy = coins / a[i];
                    if(buy > 0) 
                    {
                        ans += buy;
                        long long cost = buy * a[i];
                        coins -= cost;
                        totalcost += cost;
                    }
                }
            }
            
            printf("%d\n", ans);
            return 0;
        }
        
        • 1

        信息

        ID
        1179
        时间
        1000ms
        内存
        256MiB
        难度
        7
        标签
        递交数
        203
        已通过
        40
        上传者