[codeforces][Educational Codeforces Round 53 (Rated for Div. 2)D. Berland Fair]

http://codeforces.com/problemset/problem/1073/D

题目大意:有n个物品(n<2e5)围成一个圈,你有t(t<1e18)元,每次经过物品i,如果身上的钱可以购买该物品就直接购买,直到一件物品都不能购买,求一共可以购买多少件物品.

题目分析:由于t的数量级达到了1e18,所以不可能直接进行暴力模拟,这个时候就要想到周期性地模拟.

题解:每次遍历一下1~n这n个物品,然后计算出可以取的物品数以及价值,然后用剩下的钱除以这个价值,得到可以进行的轮数,累加到结果中,然后继续遍历..继续累加...这个方法看起来还是很暴力,但是可以证明最多进行logTl轮,也就是总时间复杂度为O(N*logT).下面是轮数为logT的证明..

复杂度的证明:遍历之前的钱数记为Tcur,可以取走的物品价值记为C,遍历并且累加之后的钱数记为Tnex,则有Tnex=Tcur%C,则可以得到Tnex<C&&Tnex<=Tcur-C,所以Tnex<Tcur/2,所以可以得到能进行的轮数也就是logT,总的复杂度也就是O(N*logT)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 ll n,t,qwq[200005];
 8 ll minn=1e12;
 9 int main(){
10    //freopen("in.txt","r",stdin);
11     cin>>n>>t;
12     for(int i=0;i<n;i++){
13         scanf("%lld",&qwq[i]);
14         minn=min(minn,qwq[i]);
15     }
16     ll ans=0;
17     while(t>=minn){
18         ll k=0;
19         ll kk=0;
20         for(int i=0;i<n;i++){
21             if(t>=qwq[i]){
22                 t-=qwq[i];
23                 k++;
24                 kk+=qwq[i];
25             }
26         }
27         ans+=k+(t/kk)*k;
28         t%=kk;
29     }
30     cout << ans << endl;
31     return 0;
32 }
View Code

猜你喜欢

转载自www.cnblogs.com/MekakuCityActor/p/9975898.html