【利用数据结构进行贪心】
【利用数据结构进行贪心】
用某数据结构进行维护
堆/单调栈/单调队列/...
灵梦的字符串问题【堆】
https://ac.nowcoder.com/acm/contest/106509/C

注意一个小细节:
优先选择ans+=的形式

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
ll abss(ll a){return a>0?a:-a;}
ll max_(ll a,ll b){return a>b?a:b;}
ll min_(ll a,ll b){return a<b?a:b;}
bool cmpll(ll a,ll b){return a>b;}
const int N=2e5+10;
/*
如何判断当前字符被复制后能使整个数组的字典序变小?
->模拟堆的形式
从后往前遍历 依次加堆 如果字符相同:弹出 否则判断堆顶是否<当前字符->若小于则说明当前点复制能变小
*/
int n;
ll m;
string s;
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
cin>>s;
vector<ll> a(n+1);
vector<bool> st(n+1);
for(int i=0;i<n;i++) cin>>a[i];
string t;
t+=s.back();
//注意string也有这些写法!
for(int i=n-2;i>=0;i--){
if(!t.empty() && t.back()==s[i]) t.pop_back();
if(t.size() && t.back()>s[i]) st[i]=1;
t+=s[i];
}
string ans;
for(int i=0;i<n;i++){
ans+=s[i];
if(st[i] && a[i]<=m){
ans+=s[i];
m-=a[i];
}
}
cout<<ans;
return 0;
}
扫雷 1【单调栈】
https://codeforces.com/gym/105158/attachments
注意读题:一个探测器可以选无数次!!!->马上否定反悔贪心
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef pair<int,int> PII;
typedef long long ll;
ll abss(ll a){return a>0?a:-a;}
ll max_(ll a,ll b){return a>b?a:b;}
ll min_(ll a,ll b){return a<b?a:b;}
bool cmpll(ll a,ll b){return a>b;}
//注意一个地雷可以在一轮买很多次!!!
/*
后面的轮中如果有一个很便宜的探测器,那么我们直接留着钱只买这个就行了,能买多少就买多少
探测器便宜又靠后->【单调栈(单调上升)】
*/
int n;
void solve(){
cin>>n;
vector<int> c(n+1,0);
for(int i=1;i<=n;i++) cin>>c[i];
//单调栈
vector<PII> pos;
for(int i=1;i<=n;i++){
while(!pos.empty() && pos.back().first>c[i]) pos.pop_back();
pos.push_back({c[i],i});
}
int ans=0,cnt=0;
int pre=0;
for(auto [c,i]:pos){
cnt+=i-pre;
int cnt1=cnt/c;
ans+=cnt1;
cnt-=cnt1*c;
pre=i;
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T=1;
//cin>>T;
while(T--) solve();
return 0;
}

浙公网安备 33010602011771号