https://blog.csdn.net/wcxyky/article/details/97617893?utm_source=app
1.给定一组数,针对每个数,寻找它和它左边第一个比它小的数之间有多少个数。
2.给定一序列,寻找某一子序列,使得子序列中的最小值乘以子序列的长度最大。
3.给定一序列,寻找某一子序列,使得子序列中的最小值乘以子序列所有元素和最大。
例题:http://poj.org/problem?id=3250
题意:有n头牛站一排且向右看,给出每条牛的高度,问每头牛可看到其他牛的头的总和和多少。
//#include<bits/stdc++.h> #include<iostream> #include<stdio.h> #include<cstring> #include<cmath> using namespace std ; typedef long long ll ; const int N = 100010, M = 200010 ; int r[N] , a[N];//找到右边第一个大于等于a[i]的数的下标 int n ; int st[N] , top ; void solve(){ for(int i = 0 ; i < n ; i++){ scanf("%d" , &a[i]); } top = 0 ; for(int i = 0 ; i < n ; i++){ while(top && a[st[top]] <= a[i]){ r[st[top]] = i ; top--; } st[++top] = i ; } while(top){ r[st[top]] = n ; top--; } ll ans = 0 ; for(int i = 0 ; i < n ; i++){ ans += r[i] - i - 1;//之间就是答案 } cout << ans << endl; } signed main(){ #ifdef ONLINE_JUDGE #else freopen("D:\c++\in.txt", "r", stdin); //freopen("D:\c++\out.txt", "w", stdout); #endif while(~scanf("%d" , &n)) solve(); }