4 条题解
-
3
#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; }//抄的学姐代码,给大家发个注释看看能不能更好理解 -
2
为了能购买最大数量的大红,我们肯定要多买价钱低的大红,那我们就去求数组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
/主要思路是找到数组中最小值的最后位置,因为越到后面钱越多,算出能买多少大红(买不了也没关系,说明前边比他大的更买不了), 然后从最小值后面开始再找最小值,重复上面操作,直到最小值为最后一个值为止/
#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
#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
- 上传者