D. Berland Fair (暴力出奇迹 + 时间复杂度证明)

题目:传送门

题意:有 n 个糖果,第 i 个糖果卖 ai 块钱,你现在有 T 块钱,你每次都从第一块糖果开始看,如果你的钱数够买当前的糖果,那么你就会花钱买它,如果你看完了所有 n 块糖果,那么你会从 1 重新开始看,直到你的钱数小于最便宜的糖果的价格。

1 <= n <= 2e5, 1 <= ai <= 1e9, 1 <= T <= 1e18

思路:直接暴力就行了。 最多跑 logT 次 for,那时间复杂度才 o(n*logT) 完全可接受。

关于复杂度的证明:

  设 C 为这一轮能买的糖果的总价格, Tcur 为这一轮之前剩下的钱, Tnew 为买完这一轮剩下的钱。

  Tnew = Tcur % C, 故 Tnew < C 且 Tnew < Tcur - C, 那 Tnew < Tcur / 2

  那这样每次都至少缩小一倍, 那就最多 logT 次。

#include <bits/stdc++.h>
#define LL long long
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF INT_MAX
#define inf LLONG_MAX
#define PI acos(-1)
using namespace std;

const int N = 1e6 + 5;

LL a[N];

void solve() {
    int n; LL T;
    scanf("%d", &n);
    scanf("%lld", &T);
    LL mi = INF;
    rep(i, 1, n) {
        scanf("%lld", &a[i]);
        mi = min(mi, a[i]);
    }
    LL ans = 0;
    while(T >= mi) {
        LL sum = 0;
        LL c = 0;
        rep(i, 1, n) {
            if(T >= a[i]) {
                sum += a[i];
                T -= a[i];
                ans++;
                c++;
            }
        }
        LL tmp = T / sum;
        ans = ans + tmp * c;
        T %= sum;
    }
    printf("%lld\n", ans);
}

int main() {

    solve();

    return 0;
}

原文地址:https://www.cnblogs.com/Willems/p/12388407.html

时间: 2024-08-06 14:20:40

D. Berland Fair (暴力出奇迹 + 时间复杂度证明)的相关文章

莫队算法——暴力出奇迹

简介: 莫队这个算法是莫涛提出的. ? 用于处理一类不带修改的区间查询问题的离线 算法,其核心在于利用曼哈顿距离最小生成树 算法对区间处理顺序进行处理 . --zrt课件 这个算法本质上其实是暴力,但是由于可以离线处理循环的顺序,使得复杂度可以从n^2降到n^根号n甚至更低. 对于可以找到以下特点的题可以尝试使用莫队: 1.莫队算法是离线处理一类区间不修改查询类问 题的算法.就是如果你知道了 [ L,R] 的答案.你 可以在 O(1 ) 或 O( lgn ) 的 时间下得到 [ L,R 1] 和

SID1190471 / 烦人的幻灯片 暴力出奇迹 !!!!!!!!!!!!!!!!!!

PID221 / 烦人的幻灯片 ☆ 提交你的代码 查看讨论和题解 你还木有做过哦 我的状态 查看最后一次评测记录 质量还不能统计出来哦~ 题目评价 质量 无 ★★★★★ ★★★★☆ ★★★☆☆ ★★☆☆☆ ★☆☆☆☆ 0% 0% 0% 0% 0% ★ ★ ★ ★ ☆ 通过人数 186 / 337 通过统计 最短耗时 0ms 最小内存 0KB 其它 题目标签 类型 其它 题目描述 李教授于今天下午做一个非常重要的演讲.不幸的是他不是一个非常爱整洁的人,他把自己做演讲要用的幻灯片随便堆放在一起.因此

烦人的幻灯片 暴力出奇迹

题目描述 李教授于今天下午做一个非常重要的演讲.不幸的是他不是一个非常爱整洁的人,他把自己做演讲要用的幻灯片随便堆放在一起.因此,演讲之前他不得不去整理这些幻灯片.做为一个讲求效率的学者,他希望尽可能简单地完成它.情况是这样,教授这次演讲一共要用n张幻灯片(n<=26),这n张幻灯片按照演讲要使用的顺序已经用数字1,2,…,n在上面编上了号.因为幻灯片是透明的,所以我们不能一下子看清每一个数字所对应的幻灯片. 现在我们用大写字母A,B,C,...再次把幻灯片依次编上号,如样例所示,我们可以很快发

51nod——1285 山峰和分段(暴力出奇迹)

要求每段的点数都一样,因此分的段数cnt肯定是n的因子,要求每段都有山峰,因此cnt肯定小于等于山峰数量.分段的宽度d=n/cnt,对山峰数量做一个前缀和,检查一下每一段的山峰数量是否没有增加即可. 1 ///暴力枚举段数 2 #include <bits/stdc++.h> 3 using namespace std; 4 #define maxn 50050 5 int high[maxn],num[maxn]; 6 7 int main(){ 8 std::ios::sync_with_

Post Lamps CodeForces - 990E(暴力出奇迹?)

题意: 在一个从0开始的连续区间上  放置几个小区间,使得这些小区间覆盖整个大区间,不同长度的小区间有不同的花费,其中有m个点,小区间的左端点不能放在这些点上 解析: 显然如果0是这m点中的一个 则无解 然后就是标记上连续不能放的点  然后遍历每一个小区间  从0开始放 求花费最小值即可 · 注意最大值的设置 代码都加了1,从1开始 #include <bits/stdc++.h> using namespace std; const int maxn = 2000006, INF = 0x7

Topcoder SRM 638 DIV 2 (大力出奇迹)

水题,就是一个暴力.大力出奇迹. Problem Statement   There is a narrow passage. Inside the passage there are some wolves. You are given a vector <int> size that contains the sizes of those wolves, from left to right. The passage is so narrow that some pairs of wolv

codeforces 897A Scarborough Fair 暴力签到

codeforces 897A Scarborough Fair 题目链接: http://codeforces.com/problemset/problem/897/A 思路: 暴力大法好 代码: #include <iostream> #include <stdio.h> #include <string.h> using namespace std; typedef long long ll; int n,m; string s; int main() { ios

CodeForces - 1073D Berland Fair

XXI Berland Annual Fair is coming really soon! Traditionally fair consists of nnbooths, arranged in a circle. The booths are numbered 11 through nn clockwise with nnbeing adjacent to 11. The ii-th booths sells some candies for the price of aiai burle

自下而上建堆(heap)的时间复杂度证明

作者:Tobin 日期:2019/04/13 缘由:看python cookbook时,用到了heapq的库,书中提到,如果仅仅是返回一个数组的最大值,用max就可以了,但是如果返回多个较大或者较小元素用堆,如果返回的个数接近于数组本身的元素个数时,直接用排序即可.那么我在想,为啥返回几个元素的时候用堆效果比较好呢?于是我翻开了尘封许久的<算法导论>. 什么是堆 堆是一种数据结构.二叉堆是一个数组,近似于一个完全二叉树.树上的每个结点对应于数组的一个元素,除了最底层外树是充满的.下面的图是一个